Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add WaveLayout

  • Loading branch information...
commit 86eb42be1b13653145e6b2c4a2a32b0fde5182d0 1 parent ca8496a
TangKe authored
View
25 Aretha/res/values/attrs.xml
@@ -13,7 +13,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
-->
<resources>
@@ -23,19 +23,20 @@
<attr name="dotSpacing" format="dimension" />
<attr name="dotColor" format="color" />
<attr name="radius" format="dimension" />
+ <attr name="interpolator" format="reference" />
+ <attr name="gravity">
+ <flag name="center" value="0x11" />
+ <flag name="top" value="0x30" />
+ <flag name="left" value="0x03" />
+ <flag name="bottom" value="0x50" />
+ <flag name="right" value="0x05" />
</attr>
<declare-styleable name="SectorView">
-
- <declare-styleable name="SectorView">
- <attr name="radius" />
- <attr name="gravity">
- <flag name="center" value="0x11" />
- <flag name="top" value="0x30" />
- <flag name="left" value="0x03" />
<attr name="radius" />
<attr name="animationOffset" format="integer" />
<attr name="duration" />
+ <attr name="interpolator" />
<attr name="gravity" />
</declare-styleable>
<declare-styleable name="AccelerateLinearDecelerateProgressBar">
@@ -74,5 +75,13 @@
<attr name="centerX" format="integer" />
<attr name="centerY" format="integer" />
<attr name="flingEnabled" format="boolean" />
+ </declare-styleable>
+ <declare-styleable name="WaveLayout">
+ <attr name="maxAmplitude" format="integer" />
+ <attr name="orientation">
+ <enum name="horizontal" value="0" />
+ <enum name="vertical" value="1" />
+ </attr>
+ <attr name="gravity" />
</declare-styleable>
View
1  Aretha/src/com/aretha/widget/ClickWheelView.java
@@ -130,7 +130,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final float radius = mRadius;
measureChildren(widthMeasureSpec, heightMeasureSpec);
-
int measureWidth = 0, measureHeight = 0;
int maxChildWidth = 0, maxChildHeight = 0;
for (int index = 0; index < count; index++) {
View
1  Aretha/src/com/aretha/widget/ToggleView.java
@@ -73,6 +73,7 @@ public ToggleView(Context context, AttributeSet attrs, int defStyle) {
mToggleState = a.getInt(R.styleable.ToggleView_toggle, 1) != 0 ? true
: false;
mClipRadius = a.getDimension(R.styleable.ToggleView_radius, 10);
+ a.recycle();
initialize(context);
}
View
185 Aretha/src/com/aretha/widget/WaveLayout.java
@@ -0,0 +1,185 @@
+package com.aretha.widget;
+
+import com.aretha.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Scroller;
+
+public class WaveLayout extends ViewGroup {
+ public static final int HORIZONTAL = 0;
+ public static final int VERTICAL = 1;
+
+ private int mGravity;
+ private int mOrientation;
+
+ private int mCurrentWaveCrestPosition;
+ private int mCurrentWaveAmplitude;
+ private int mMaxWaveAmplitude;
+
+ private Scroller mScroller;
+
+ public WaveLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.WaveLayout);
+ mMaxWaveAmplitude = a.getInteger(R.styleable.WaveLayout_maxAmplitude,
+ (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ 80, context.getResources().getDisplayMetrics()));
+ mOrientation = a.getInt(R.styleable.WaveLayout_orientation, HORIZONTAL);
+ mGravity = a.getInt(R.styleable.WaveLayout_gravity, Gravity.BOTTOM);
+ a.recycle();
+ initialize(context);
+ }
+
+ public WaveLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public WaveLayout(Context context) {
+ this(context, null);
+ }
+
+ private void initialize(Context context) {
+ mScroller = new Scroller(context);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int childCount = getChildCount();
+ final int currentWaveCrestPosition = mCurrentWaveCrestPosition;
+ final boolean isHorizontal = mOrientation == HORIZONTAL;
+ final int currentWaveRadius = mCurrentWaveAmplitude;
+ final int gravity = mGravity;
+
+ int height = b - t;
+ int width = r - l;
+ int offset = 0;
+ for (int index = 0; index < childCount; index++) {
+ View child = getChildAt(index);
+ int childWidth = child.getMeasuredWidth();
+ int childHeight = child.getMeasuredHeight();
+ int position = computeChildPosition(childWidth, childHeight,
+ offset, currentWaveCrestPosition, currentWaveRadius,
+ isHorizontal);
+
+ if (isHorizontal) {
+ switch (gravity) {
+ case Gravity.TOP:
+ child.layout(offset, position, offset + childWidth,
+ childHeight + position);
+ break;
+ case Gravity.BOTTOM:
+ child.layout(offset, height - childHeight - position,
+ offset + childWidth, height - position);
+ break;
+ }
+
+ } else {
+ switch (gravity) {
+ case Gravity.LEFT:
+ child.layout(position, offset, position + childWidth,
+ offset + childHeight);
+ break;
+ case Gravity.RIGHT:
+ child.layout(width - position - childWidth, offset, width
+ - position, offset + childHeight);
+ break;
+ }
+
+ }
+
+ offset += isHorizontal ? childWidth : childHeight;
+ }
+ }
+
+ protected int computeChildPosition(int width, int height, int offset,
+ int currentWaveCrestPosition, int waveRadius, boolean isHorizontal) {
+ int var = (isHorizontal ? offset + width / 2 : offset + height / 2)
+ - currentWaveCrestPosition;
+ return (int) (Math.max(0, -Math.pow(var, 2) / waveRadius / 2
+ + waveRadius));
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ measureChildren(widthMeasureSpec, heightMeasureSpec);
+ final int childCount = getChildCount();
+
+ int maxChildWidth = 0, maxChildHeight = 0;
+ int totalChildrenWidth = 0, totalChildHeight = 0;
+
+ for (int index = 0; index < childCount; index++) {
+ View child = getChildAt(index);
+ int measuredChildWidth = child.getMeasuredWidth();
+ int measuredChildHeight = child.getMeasuredHeight();
+
+ totalChildrenWidth += measuredChildWidth;
+ totalChildHeight += measuredChildHeight;
+
+ maxChildWidth = Math.max(maxChildWidth, measuredChildWidth);
+ maxChildHeight = Math.max(maxChildHeight, measuredChildHeight);
+ }
+
+ int measuredWidth = 0;
+ int measuredHeight = 0;
+
+ switch (mOrientation) {
+ case HORIZONTAL:
+ measuredWidth = totalChildrenWidth;
+ measuredHeight = maxChildHeight + mCurrentWaveAmplitude;
+ break;
+ case VERTICAL:
+ measuredWidth = maxChildWidth + mCurrentWaveAmplitude;
+ measuredHeight = totalChildHeight;
+ break;
+ }
+
+ measuredWidth += getPaddingLeft() + getPaddingRight();
+ measuredHeight += getPaddingTop() + getPaddingBottom();
+
+ setMeasuredDimension(resolveSize(measuredWidth, widthMeasureSpec),
+ resolveSize(measuredHeight, heightMeasureSpec));
+ }
+
+ @Override
+ public void computeScroll() {
+ super.computeScroll();
+ if (mScroller.computeScrollOffset()) {
+ mCurrentWaveAmplitude = mScroller.getCurrX();
+ invalidate();
+ requestLayout();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ boolean result = super.onTouchEvent(event);
+ switch (event.getAction()) {
+
+ case MotionEvent.ACTION_DOWN:
+ mScroller.startScroll(mCurrentWaveAmplitude, 0, mMaxWaveAmplitude
+ - mCurrentWaveAmplitude, 0);
+ case MotionEvent.ACTION_MOVE:
+ mCurrentWaveCrestPosition = (int) (mOrientation == HORIZONTAL ? event
+ .getX() : event.getY());
+ result = true;
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_OUTSIDE:
+ mScroller.startScroll(mCurrentWaveAmplitude, 0,
+ 0 - mCurrentWaveAmplitude, 0);
+ break;
+ }
+ invalidate();
+ requestLayout();
+ return result;
+ }
+}
View
9 ArethaDemos/AndroidManifest.xml
@@ -90,6 +90,15 @@
<category android:name="com.aretha.category.SAMPLE_CODE" />
</intent-filter>
</activity>
+ <activity
+ android:name=".widget.WaveLayoutDemo"
+ android:label="@string/wave_layout" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.aretha.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
View
157 ArethaDemos/res/layout/wave_layout.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aretha="http://schemas.android.com/apk/res/com.arethademo" >
+
+ <com.aretha.widget.WaveLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|center_vertical"
+ aretha:gravity="right"
+ aretha:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+ </com.aretha.widget.WaveLayout>
+
+ <com.aretha.widget.WaveLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ aretha:gravity="left"
+ aretha:orientation="vertical" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+ </com.aretha.widget.WaveLayout>
+
+ <com.aretha.widget.WaveLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ aretha:gravity="top"
+ aretha:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+ </com.aretha.widget.WaveLayout>
+
+ <com.aretha.widget.WaveLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ aretha:gravity="bottom"
+ aretha:orientation="horizontal" >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/logo" />
+ </com.aretha.widget.WaveLayout>
+
+</merge>
View
3  ArethaDemos/res/values/strings.xml
@@ -79,5 +79,8 @@
<string name="bitmap_effect_builder_glow_with_original">Glow with Original</string>
<string name="bitmap_effect_builder_reflection_without_original">Reflection without Original</string>
<string name="bitmap_effect_builder_reflection_with_original">Reflection with Original</string>
+
+ <!-- WaveLayout -->
+ <string name="wave_layout">WaveLayout</string>
</resources>
View
14 ArethaDemos/src/com/arethademo/widget/WaveLayoutDemo.java
@@ -0,0 +1,14 @@
+package com.arethademo.widget;
+
+import com.arethademo.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class WaveLayoutDemo extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.wave_layout);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.