resolved conflicts for merge of 607b9c37 to eclair-mr2-plus-aosp

This commit is contained in:
Jim Miller
2009-11-16 14:08:24 -08:00

View File

@@ -19,6 +19,7 @@ package com.android.internal.widget;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
@@ -30,6 +31,12 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ImageView.ScaleType;
@@ -45,17 +52,18 @@ import com.android.internal.R;
*
*/
public class SlidingTab extends ViewGroup {
private static final int ANIMATION_DURATION = 250; // animation transition duration (in ms)
private static final String LOG_TAG = "SlidingTab";
private static final boolean DBG = false;
private static final int HORIZONTAL = 0; // as defined in attrs.xml
private static final int VERTICAL = 1;
private static final int MSG_ANIMATE = 100;
// TODO: Make these configurable
private static final float THRESHOLD = 2.0f / 3.0f;
private static final long VIBRATE_SHORT = 30;
private static final long VIBRATE_LONG = 40;
private static final int TRACKING_MARGIN = 50;
private static final int ANIM_DURATION = 250; // Time for most animations (in ms)
private static final int ANIM_TARGET_TIME = 500; // Time to show targets (in ms)
private OnTriggerListener mOnTriggerListener;
private int mGrabbedState = OnTriggerListener.NO_HANDLE;
@@ -63,8 +71,6 @@ public class SlidingTab extends ViewGroup {
private Vibrator mVibrator;
private float mDensity; // used to scale dimensions for bitmaps.
private final SlidingTabHandler mHandler = new SlidingTabHandler();
/**
* Either {@link #HORIZONTAL} or {@link #VERTICAL}.
*/
@@ -77,6 +83,7 @@ public class SlidingTab extends ViewGroup {
private float mThreshold;
private Slider mOtherSlider;
private boolean mAnimating;
private Rect mTmpRect;
/**
* Interface definition for a callback to be invoked when a tab is triggered
@@ -121,6 +128,12 @@ public class SlidingTab extends ViewGroup {
void onGrabbedStateChange(View v, int grabbedState);
}
// TODO: For debugging; remove after glitches debugged.
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
}
/**
* Simple container class for all things pertinent to a slider.
* A slider consists of 3 Views:
@@ -138,6 +151,7 @@ public class SlidingTab extends ViewGroup {
public static final int ALIGN_RIGHT = 1;
public static final int ALIGN_TOP = 2;
public static final int ALIGN_BOTTOM = 3;
public static final int ALIGN_UNKNOWN = 4;
/**
* States for the view.
@@ -150,6 +164,8 @@ public class SlidingTab extends ViewGroup {
private final TextView text;
private final ImageView target;
private int currentState = STATE_NORMAL;
private int alignment = ALIGN_UNKNOWN;
private int alignment_value;
/**
* Constructor
@@ -205,12 +221,36 @@ public class SlidingTab extends ViewGroup {
}
void hide() {
// TODO: Animate off the screen
text.setVisibility(View.INVISIBLE);
tab.setVisibility(View.INVISIBLE);
boolean horiz = alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT;
int dx = horiz ? (alignment == ALIGN_LEFT ? alignment_value - tab.getRight()
: alignment_value - tab.getLeft()) : 0;
int dy = horiz ? 0 : (alignment == ALIGN_TOP ? alignment_value - tab.getBottom()
: alignment_value - tab.getTop());
Animation trans = new TranslateAnimation(0, dx, 0, dy);
trans.setDuration(ANIM_DURATION);
trans.setFillAfter(true);
tab.startAnimation(trans);
text.startAnimation(trans);
target.setVisibility(View.INVISIBLE);
}
void show(boolean animate) {
text.setVisibility(View.VISIBLE);
tab.setVisibility(View.VISIBLE);
//target.setVisibility(View.INVISIBLE);
if (animate) {
boolean horiz = alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT;
int dx = horiz ? (alignment == ALIGN_LEFT ? tab.getWidth() : -tab.getWidth()) : 0;
int dy = horiz ? 0: (alignment == ALIGN_TOP ? tab.getHeight() : -tab.getHeight());
Animation trans = new TranslateAnimation(-dx, 0, -dy, 0);
trans.setDuration(ANIM_DURATION);
tab.startAnimation(trans);
text.startAnimation(trans);
}
}
void setState(int state) {
text.setPressed(state == STATE_PRESSED);
tab.setPressed(state == STATE_PRESSED);
@@ -230,15 +270,39 @@ public class SlidingTab extends ViewGroup {
}
void showTarget() {
AlphaAnimation alphaAnim = new AlphaAnimation(0.0f, 1.0f);
alphaAnim.setDuration(ANIM_TARGET_TIME);
target.startAnimation(alphaAnim);
target.setVisibility(View.VISIBLE);
target.startAnimation(alphaAnim);
}
void reset() {
void reset(boolean animate) {
setState(STATE_NORMAL);
text.setVisibility(View.VISIBLE);
text.setTextAppearance(text.getContext(), R.style.TextAppearance_SlidingTabNormal);
tab.setVisibility(View.VISIBLE);
target.setVisibility(View.INVISIBLE);
final boolean horiz = alignment == ALIGN_LEFT || alignment == ALIGN_RIGHT;
int dx = horiz ? (alignment == ALIGN_LEFT ? alignment_value - tab.getLeft()
: alignment_value - tab.getRight()) : 0;
int dy = horiz ? 0 : (alignment == ALIGN_TOP ? alignment_value - tab.getTop()
: alignment_value - tab.getBottom());
if (animate) {
TranslateAnimation trans = new TranslateAnimation(0, dx, 0, dy);
trans.setDuration(ANIM_DURATION);
trans.setFillAfter(false);
text.startAnimation(trans);
tab.startAnimation(trans);
} else {
if (horiz) {
text.offsetLeftAndRight(dx);
tab.offsetLeftAndRight(dx);
} else {
text.offsetTopAndBottom(dy);
tab.offsetTopAndBottom(dy);
}
}
}
void setTarget(int targetId) {
@@ -255,6 +319,7 @@ public class SlidingTab extends ViewGroup {
* @param alignment which side to align the widget to
*/
void layout(int l, int t, int r, int b, int alignment) {
this.alignment = alignment;
final Drawable tabBackground = tab.getBackground();
final int handleWidth = tabBackground.getIntrinsicWidth();
final int handleHeight = tabBackground.getIntrinsicHeight();
@@ -280,11 +345,13 @@ public class SlidingTab extends ViewGroup {
text.layout(0 - parentWidth, top, 0, bottom);
text.setGravity(Gravity.RIGHT);
target.layout(leftTarget, targetTop, leftTarget + targetWidth, targetBottom);
alignment_value = l;
} else {
tab.layout(parentWidth - handleWidth, top, parentWidth, bottom);
text.layout(parentWidth, top, parentWidth + parentWidth, bottom);
target.layout(rightTarget, targetTop, rightTarget + targetWidth, targetBottom);
text.setGravity(Gravity.TOP);
alignment_value = r;
}
} else {
// vertical
@@ -296,10 +363,12 @@ public class SlidingTab extends ViewGroup {
tab.layout(left, 0, right, handleHeight);
text.layout(left, 0 - parentHeight, right, 0);
target.layout(targetLeft, top, targetRight, top + targetHeight);
alignment_value = t;
} else {
tab.layout(left, parentHeight - handleHeight, right, parentHeight);
text.layout(left, parentHeight, right, parentHeight + parentHeight);
target.layout(targetLeft, bottom, targetRight, bottom + targetHeight);
alignment_value = b;
}
}
}
@@ -333,6 +402,12 @@ public class SlidingTab extends ViewGroup {
public int getTabHeight() {
return tab.getMeasuredHeight();
}
public void startAnimation(Animation animation) {
tab.startAnimation(animation);
text.startAnimation(animation);
target.setVisibility(View.GONE);
}
}
public SlidingTab(Context context) {
@@ -345,6 +420,9 @@ public class SlidingTab extends ViewGroup {
public SlidingTab(Context context, AttributeSet attrs) {
super(context, attrs);
// Allocate a temporary once that can be used everywhere.
mTmpRect = new Rect();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingTab);
mOrientation = a.getInt(R.styleable.SlidingTab_orientation, HORIZONTAL);
a.recycle();
@@ -401,19 +479,17 @@ public class SlidingTab extends ViewGroup {
final float x = event.getX();
final float y = event.getY();
final Rect frame = new Rect();
if (mAnimating) {
return false;
}
View leftHandle = mLeftSlider.tab;
leftHandle.getHitRect(frame);
boolean leftHit = frame.contains((int) x, (int) y);
leftHandle.getHitRect(mTmpRect);
boolean leftHit = mTmpRect.contains((int) x, (int) y);
View rightHandle = mRightSlider.tab;
rightHandle.getHitRect(frame);
boolean rightHit = frame.contains((int)x, (int) y);
rightHandle.getHitRect(mTmpRect);
boolean rightHit = mTmpRect.contains((int)x, (int) y);
if (!mTracking && !(leftHit || rightHit)) {
return false;
@@ -451,40 +527,31 @@ public class SlidingTab extends ViewGroup {
final int action = event.getAction();
final float x = event.getX();
final float y = event.getY();
final View handle = mCurrentSlider.tab;
switch (action) {
case MotionEvent.ACTION_MOVE:
moveHandle(x, y);
float position = isHorizontal() ? x : y;
float target = mThreshold * (isHorizontal() ? getWidth() : getHeight());
boolean thresholdReached;
if (isHorizontal()) {
thresholdReached = mCurrentSlider == mLeftSlider ?
position > target : position < target;
} else {
thresholdReached = mCurrentSlider == mLeftSlider ?
position < target : position > target;
}
if (!mTriggered && thresholdReached) {
mTriggered = true;
mTracking = false;
mCurrentSlider.setState(Slider.STATE_ACTIVE);
dispatchTriggerEvent(mCurrentSlider == mLeftSlider ?
OnTriggerListener.LEFT_HANDLE : OnTriggerListener.RIGHT_HANDLE);
if (withinView(x, y, this) ) {
moveHandle(x, y);
float position = isHorizontal() ? x : y;
float target = mThreshold * (isHorizontal() ? getWidth() : getHeight());
boolean thresholdReached;
if (isHorizontal()) {
thresholdReached = mCurrentSlider == mLeftSlider ?
position > target : position < target;
} else {
thresholdReached = mCurrentSlider == mLeftSlider ?
position < target : position > target;
}
if (!mTriggered && thresholdReached) {
mTriggered = true;
mTracking = false;
mCurrentSlider.setState(Slider.STATE_ACTIVE);
dispatchTriggerEvent(mCurrentSlider == mLeftSlider ?
OnTriggerListener.LEFT_HANDLE : OnTriggerListener.RIGHT_HANDLE);
// TODO: This is a place holder for the real animation. It just holds
// the screen for the duration of the animation for now.
mAnimating = true;
mHandler.postDelayed(new Runnable() {
public void run() {
resetView();
mAnimating = false;
}
}, ANIMATION_DURATION);
}
if (isHorizontal() && (y <= handle.getBottom() && y >= handle.getTop()) ||
!isHorizontal() && (x >= handle.getLeft() && x <= handle.getRight()) ) {
startAnimating();
setGrabbedState(OnTriggerListener.NO_HANDLE);
}
break;
}
// Intentionally fall through - we're outside tracking rectangle
@@ -493,7 +560,10 @@ public class SlidingTab extends ViewGroup {
case MotionEvent.ACTION_CANCEL:
mTracking = false;
mTriggered = false;
resetView();
mOtherSlider.show(true);
mCurrentSlider.reset(false);
mCurrentSlider = null;
mOtherSlider = null;
setGrabbedState(OnTriggerListener.NO_HANDLE);
break;
}
@@ -502,14 +572,68 @@ public class SlidingTab extends ViewGroup {
return mTracking || super.onTouchEvent(event);
}
void startAnimating() {
mAnimating = true;
final Animation appear = new AlphaAnimation(0.5f, 1.0f); appear.setDuration(ANIM_DURATION);
final Animation trans;
Slider slider = mCurrentSlider;
int dx;
int dy;
if (isHorizontal()) {
int right = slider.tab.getRight();
int width = slider.tab.getWidth();
int left = slider.tab.getLeft();
int viewWidth = getWidth();
dx = slider == mRightSlider ? - (right + viewWidth - width)
: (viewWidth - left) + viewWidth - width;
dy = 0;
} else {
int top = slider.tab.getTop();
int bottom = slider.tab.getBottom();
int height = slider.tab.getHeight();
int viewHeight = getHeight();
dx = 0;
dy = slider == mRightSlider ? (top + viewHeight - height)
: - ((viewHeight - bottom) + viewHeight - height);
}
trans = new TranslateAnimation(0, dx, 0, dy);
trans.setDuration(ANIM_DURATION);
trans.setInterpolator(new LinearInterpolator());
trans.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
resetView();
mLeftSlider.startAnimation(appear);
mRightSlider.startAnimation(appear);
mAnimating = false;
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationStart(Animation animation) {
}
});
slider.startAnimation(trans);
}
private boolean withinView(final float x, final float y, final View view) {
return isHorizontal() && y > - TRACKING_MARGIN && y < TRACKING_MARGIN + view.getHeight()
|| !isHorizontal() && x > -TRACKING_MARGIN && x < TRACKING_MARGIN + view.getWidth();
}
private boolean isHorizontal() {
return mOrientation == HORIZONTAL;
}
private void resetView() {
mLeftSlider.reset();
mRightSlider.reset();
onLayout(true, getLeft(), getTop(), getLeft() + getWidth(), getTop() + getHeight());
mLeftSlider.reset(false);
mRightSlider.reset(false);
// onLayout(true, getLeft(), getTop(), getLeft() + getWidth(), getTop() + getHeight());
}
@Override
@@ -642,22 +766,6 @@ public class SlidingTab extends ViewGroup {
}
}
private class SlidingTabHandler extends Handler {
public void handleMessage(Message m) {
switch (m.what) {
case MSG_ANIMATE:
doAnimation();
break;
}
}
}
private void doAnimation() {
if (mAnimating) {
}
}
private void log(String msg) {
Log.d(LOG_TAG, msg);
}