标签:des android style blog http io ar color os
http://blog.csdn.net/lovehong0306
前几天项目需要用到左侧拉出抽屉,想到了http://blog.csdn.net/hellogv/article/details/6264706中提到的多方抽屉,拿来试用了下,发现bug还真不少,最不能忍受的是最后那一下“闪烁”,于是乎,改!
下面将修改过程中遇到的问题及其解决方法分享给大家。
首先是出现了如图的情况:
当以光的速度点击handle(就是那个带箭头的Button)并拉出到很远很远的地方 就出先上边那个神奇的现象了
寻找原因,发现是这里的问题
-
<span style="white-space:pre"> </span>if (tmpX != mTrackX || tmpY != mTrackY)
-
{
-
mTrackX = tmpX;
-
mTrackY = tmpY;
-
-
}
-
invalidate();
就拿上边那种情况来讲
当瞬间将handle拉至最大位置,即 tmpX=0 的位置,由于mTrackX默认为0,if条件不成立,执行不到invalidate()方法,页面没有刷新
将invalidate()方法移到if‘条件语句之外即可解决问题
下一问题:onFling方法在将抽屉快速抽出时基本不能用
抽出来~滑进去~抽出来~滑进去~ (这个抽屉带弹簧的@_@?!)
究其原因,在这里
-
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-
mState = State.FLYING;
-
mVelocity = mOrientation == VERTICAL? velocityY : velocityX;
-
post(startAnimation);
-
return true;
-
}
mVelocity 使用的是onFling方法传进来的参数velocityX,经多次打印log发现velocityX为负数大致看了下源码,这个速度是基于getX()方法算出来的是
大家都知道,getX()方法是获取以widget左上角为坐标原点计算的X轴坐标值(不知道的看这里:http://blog.csdn.net/lovehong0306/article/details/7451507)
由此推想而知
1.点击handle(此时content为GONE),这时的getX()得到的是以handle左上角为原点的坐标
2.快速滑动以发动onFling方法(快到只有两个event事件发生),这时getX()得到的依然是以handle的左上角为原点的坐标,但是由于content已经可见,handle的位置发生了变化,为抽屉完全抽出时的位置,而action_up事件发生时的getX()得到是在handle原点的左边,即为负值,用此时的X坐标值减去之前得到的那个正的坐标值,结果当然是负的了
3.有负的偏移量和时间,计算出来的速度也就是负的了
这就是为什么拉出抽屉后会滑进去的原因了
修改为如下即可解决:
-
@Override
-
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-
float velocityY)
-
{
-
mState = State.FLYING;
-
-
float velocityX2, velocityY2;
-
if (lastRawX == -1 && lastRawY == -1)
-
{
-
velocityX2 = (curRawX - e1.getRawX())
-
/ (curEventTime - e1.getEventTime()) * 1000;
-
velocityY2 = (curRawY - e1.getRawY())
-
/ (curEventTime - e1.getEventTime()) * 1000;
-
}
-
else
-
{
-
velocityX2 = (curRawX - lastRawX)
-
/ (curEventTime - lastEventTime) * 1000;
-
velocityY2 = (curRawY - lastRawY)
-
/ (curEventTime - lastEventTime) * 1000;
-
}
-
-
mVelocity = mOrientation == VERTICAL ? velocityY2 : velocityX2;
-
-
if (Math.abs(mVelocity) > 50)
-
{
-
if (mVelocity > 0)
-
{
-
mAnimatedAcceleration = mMaximumAcceleration;
-
}
-
else
-
{
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
}
-
-
long now = SystemClock.uptimeMillis();
-
mAnimationLastTime = now;
-
mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
-
mAnimating = true;
-
mHandler.removeMessages(MSG_ANIMATE);
-
mHandler.removeMessages(MSG_PREPARE_ANIMATE);
-
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
-
mCurrentAnimationTime);
-
return true;
-
}
-
return false;
-
}
代码就不多做解释了,命名还算规范,应该能看懂,最后那几行是为解决“闪烁”问题的
下面就来说下最棘手的问题——“闪烁”
那么为什么会闪烁呢?
经多次尝试,发现是动画与setVisibility(GONG)冲突,当把动画设置为setFillAfter(true)后即可发现,动画结束后设置控件setVisibility(GONG),消失的不仅仅是content,handle也一同消失了。
由此可知handle在动画结束后先消失再出现,于是就出现了闪烁的效果
那么好办,只要把content和handle分别同时设置动画不就行了,content在动画结束后setVisibility(GONG),handle不setVisibility(GONG)。
But,这么尝试了一下发现,虽然“几乎”同时start动画,毕竟还是有时间间隔的,机子性能越差越明显,content和handle分开了!!!
此法行不通,另想他法
源码真是个好东西,看看SlidingDrawer是怎么实现的
原来如此,没用系统动画,利用handler重复改变控件位置
好,就按照这个思路,结合当前代码,改!
(完整代码稍后贴出)
把所有post(startAnimation)替换成:
-
long now = SystemClock.uptimeMillis();
-
mAnimationLastTime = now;
-
mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
-
mAnimating = true;
-
mHandler.removeMessages(MSG_ANIMATE);
-
mHandler.removeMessages(MSG_PREPARE_ANIMATE);
-
mHandler.sendMessageAtTime(
-
mHandler.obtainMessage(MSG_PREPARE_ANIMATE),
-
mCurrentAnimationTime);
这段代码基本上是从SlidingDrawer源码copy过来的,MSG_PREPARE_ANIMATE是自己加的
起初不明白ANIMATION_FRAME_DURATION的作用,为什么要延迟呢?
后来发现,这个延迟是留给onLayout方法的,如果不加这个延迟,后边用到的方法就可能在onLayout方法之前调用,也就导致了在onLayout方法之前用到了mContentWidth或者mContentHeight,此时的值为0,这也是为什么要另加MSG_PREPARE_ANIMATE
prepareAnimation方法代码如下:
其中类似
-
if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE)
-
{
-
mTrackX = -mContentWidth;
-
}
代码是为解决初次使用控件初始化mTrackX,否则此时单击handle会导致控件直接抽出,无动画效果
-
if (mState == State.TRACKING)
-
{
-
if (mIsShrinking)
-
{
-
if ((mOrientation == VERTICAL && Math.abs(mTrackY) < mContentHeight / 2)
-
|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) < mContentWidth <span style="white-space:pre"> </span>/ 2))
-
{
-
mVelocity = -mVelocity;
-
mAnimatedAcceleration = -mAnimatedAcceleration;
-
mIsShrinking = !mIsShrinking;
-
}
-
}
-
else
-
{
-
if ((mOrientation == VERTICAL && Math.abs(mTrackY) > mContentHeight / 2)
-
|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) > mContentWidth <span style="white-space:pre"> </span>/ 2))
-
{
-
mVelocity = -mVelocity;
-
mAnimatedAcceleration = -mAnimatedAcceleration;
-
mIsShrinking = !mIsShrinking;
-
}
-
}
-
}
这段代码是判断抽屉拉出是否过半,也就是决定控件在松开鼠标时是回到关闭状态还是抽出状态
doAnimation()方法比较简单,没啥可讲的
之前的变量 mDuration mLinearFlying mInterpolator 没用到,因为感觉没啥用,目前的控件已能满足大部分人需求,有特殊需求的请自行添加
下面上完整代码,不懂的可以留言问我
初次写博文,不周之处,还请见谅
Panel.java
-
package org.miscwidgets.widget;
-
-
import org.miscwidgets.R;
-
-
import android.content.Context;
-
import android.content.res.TypedArray;
-
import android.graphics.Canvas;
-
import android.graphics.drawable.Drawable;
-
import android.os.Handler;
-
import android.os.Message;
-
import android.os.SystemClock;
-
import android.util.AttributeSet;
-
import android.util.Log;
-
import android.view.GestureDetector;
-
import android.view.MotionEvent;
-
import android.view.View;
-
import android.view.ViewGroup;
-
import android.view.ViewParent;
-
import android.view.GestureDetector.OnGestureListener;
-
import android.view.animation.Interpolator;
-
import android.widget.FrameLayout;
-
import android.widget.LinearLayout;
-
-
-
-
-
-
public class Panel extends LinearLayout
-
{
-
-
private static final String TAG = "Panel";
-
-
private static final float MAXIMUM_MAJOR_VELOCITY = 200.0f;
-
private static final float MAXIMUM_ACCELERATION = 2000.0f;
-
private static final int MSG_ANIMATE = 1000;
-
private static final int MSG_PREPARE_ANIMATE = 2000;
-
private static final int ANIMATION_FRAME_DURATION = 1000 / 60;
-
-
private final Handler mHandler = new SlidingHandler();
-
private float mAnimatedAcceleration;
-
private long mAnimationLastTime;
-
private long mCurrentAnimationTime;
-
private boolean mAnimating;
-
-
private final int mMaximumMajorVelocity;
-
private final int mMaximumAcceleration;
-
-
private float lastRawX, lastRawY, curRawX, curRawY;
-
private float lastEventTime, curEventTime;
-
-
-
-
-
public static interface OnPanelListener
-
{
-
-
-
-
public void onPanelClosed(Panel panel);
-
-
-
-
-
public void onPanelOpened(Panel panel);
-
}
-
-
private boolean mIsShrinking;
-
private int mPosition;
-
private int mDuration;
-
private boolean mLinearFlying;
-
private int mHandleId;
-
private int mContentId;
-
private View mHandle;
-
private View mContent;
-
private Drawable mOpenedHandle;
-
private Drawable mClosedHandle;
-
private float mTrackX;
-
private float mTrackY;
-
private float mVelocity;
-
-
private OnPanelListener panelListener;
-
-
public static final int TOP = 0;
-
public static final int BOTTOM = 1;
-
public static final int LEFT = 2;
-
public static final int RIGHT = 3;
-
-
private enum State
-
{
-
ABOUT_TO_ANIMATE, ANIMATING, READY, TRACKING, FLYING, CLICK
-
};
-
-
private State mState;
-
private Interpolator mInterpolator;
-
private GestureDetector mGestureDetector;
-
private int mContentHeight;
-
private int mContentWidth;
-
private int mOrientation;
-
private float mWeight;
-
private PanelOnGestureListener mGestureListener;
-
private boolean mBringToFront;
-
-
public Panel(Context context, AttributeSet attrs)
-
{
-
super(context, attrs);
-
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Panel);
-
mDuration = a.getInteger(R.styleable.Panel_animationDuration, 750);
-
mPosition = a.getInteger(R.styleable.Panel_position, BOTTOM);
-
mLinearFlying = a.getBoolean(R.styleable.Panel_linearFlying, false);
-
mWeight = a.getFraction(R.styleable.Panel_weight, 0, 1, 0.0f);
-
if (mWeight < 0 || mWeight > 1)
-
{
-
mWeight = 0.0f;
-
Log.w(TAG, a.getPositionDescription()
-
+ ": weight must be > 0 and <= 1");
-
}
-
mOpenedHandle = a.getDrawable(R.styleable.Panel_openedHandle);
-
mClosedHandle = a.getDrawable(R.styleable.Panel_closedHandle);
-
-
RuntimeException e = null;
-
mHandleId = a.getResourceId(R.styleable.Panel_handle, 0);
-
if (mHandleId == 0)
-
{
-
e = new IllegalArgumentException(
-
a.getPositionDescription()
-
+ ": The handle attribute is required and must refer to a valid child.");
-
}
-
mContentId = a.getResourceId(R.styleable.Panel_content, 0);
-
if (mContentId == 0)
-
{
-
e = new IllegalArgumentException(
-
a.getPositionDescription()
-
+ ": The content attribute is required and must refer to a valid child.");
-
}
-
a.recycle();
-
-
final float density = getResources().getDisplayMetrics().density;
-
mMaximumMajorVelocity = (int) (MAXIMUM_MAJOR_VELOCITY * density + 0.5f);
-
mMaximumAcceleration = (int) (MAXIMUM_ACCELERATION * density + 0.5f);
-
-
if (e != null)
-
{
-
throw e;
-
}
-
mOrientation = (mPosition == TOP || mPosition == BOTTOM) ? VERTICAL
-
: HORIZONTAL;
-
setOrientation(mOrientation);
-
mState = State.READY;
-
mGestureListener = new PanelOnGestureListener();
-
mGestureDetector = new GestureDetector(mGestureListener);
-
mGestureDetector.setIsLongpressEnabled(false);
-
-
-
setBaselineAligned(false);
-
}
-
-
-
-
-
-
-
-
-
public void setOnPanelListener(OnPanelListener onPanelListener)
-
{
-
panelListener = onPanelListener;
-
}
-
-
-
-
-
-
-
public View getHandle()
-
{
-
return mHandle;
-
}
-
-
-
-
-
-
-
public View getContent()
-
{
-
return mContent;
-
}
-
-
-
-
-
-
-
-
public void setInterpolator(Interpolator i)
-
{
-
mInterpolator = i;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
public boolean setOpen(boolean open, boolean animate)
-
{
-
if (mState == State.READY && isOpen() ^ open)
-
{
-
mIsShrinking = !open;
-
if (animate)
-
{
-
mState = State.ABOUT_TO_ANIMATE;
-
if (!mIsShrinking)
-
{
-
-
-
-
mContent.setVisibility(VISIBLE);
-
}
-
long now = SystemClock.uptimeMillis();
-
mAnimationLastTime = now;
-
mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
-
mAnimating = true;
-
mHandler.removeMessages(MSG_ANIMATE);
-
mHandler.removeMessages(MSG_PREPARE_ANIMATE);
-
mHandler.sendMessageAtTime(
-
mHandler.obtainMessage(MSG_PREPARE_ANIMATE),
-
mCurrentAnimationTime);
-
}
-
else
-
{
-
mContent.setVisibility(open ? VISIBLE : GONE);
-
postProcess();
-
}
-
return true;
-
}
-
return false;
-
}
-
-
-
-
-
-
-
public boolean isOpen()
-
{
-
return mContent.getVisibility() == VISIBLE;
-
}
-
-
@Override
-
protected void onFinishInflate()
-
{
-
super.onFinishInflate();
-
mHandle = findViewById(mHandleId);
-
if (mHandle == null)
-
{
-
String name = getResources().getResourceEntryName(mHandleId);
-
throw new RuntimeException(
-
"Your Panel must have a child View whose id attribute is ‘R.id."
-
+ name + "‘");
-
}
-
mHandle.setClickable(true);
-
mHandle.setOnTouchListener(touchListener);
-
-
-
mContent = findViewById(mContentId);
-
if (mContent == null)
-
{
-
String name = getResources().getResourceEntryName(mHandleId);
-
throw new RuntimeException(
-
"Your Panel must have a child View whose id attribute is ‘R.id."
-
+ name + "‘");
-
}
-
-
-
removeView(mHandle);
-
removeView(mContent);
-
if (mPosition == TOP || mPosition == LEFT)
-
{
-
addView(mContent);
-
addView(mHandle);
-
}
-
else
-
{
-
addView(mHandle);
-
addView(mContent);
-
}
-
-
if (mClosedHandle != null)
-
{
-
mHandle.setBackgroundDrawable(mClosedHandle);
-
}
-
mContent.setClickable(true);
-
mContent.setVisibility(GONE);
-
if (mWeight > 0)
-
{
-
ViewGroup.LayoutParams params = mContent.getLayoutParams();
-
if (mOrientation == VERTICAL)
-
{
-
params.height = ViewGroup.LayoutParams.FILL_PARENT;
-
}
-
else
-
{
-
params.width = ViewGroup.LayoutParams.FILL_PARENT;
-
}
-
mContent.setLayoutParams(params);
-
}
-
}
-
-
@Override
-
protected void onAttachedToWindow()
-
{
-
super.onAttachedToWindow();
-
ViewParent parent = getParent();
-
if (parent != null && parent instanceof FrameLayout)
-
{
-
mBringToFront = true;
-
}
-
}
-
-
@Override
-
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
-
{
-
if (mWeight > 0 && mContent.getVisibility() == VISIBLE)
-
{
-
View parent = (View) getParent();
-
if (parent != null)
-
{
-
if (mOrientation == VERTICAL)
-
{
-
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
-
(int) (parent.getHeight() * mWeight),
-
MeasureSpec.EXACTLY);
-
}
-
else
-
{
-
widthMeasureSpec = MeasureSpec.makeMeasureSpec(
-
(int) (parent.getWidth() * mWeight),
-
MeasureSpec.EXACTLY);
-
}
-
}
-
}
-
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
}
-
-
@Override
-
protected void onLayout(boolean changed, int l, int t, int r, int b)
-
{
-
super.onLayout(changed, l, t, r, b);
-
mContentWidth = mContent.getWidth();
-
mContentHeight = mContent.getHeight();
-
}
-
-
@Override
-
protected void dispatchDraw(Canvas canvas)
-
{
-
-
-
-
-
if (mState == State.ABOUT_TO_ANIMATE && !mIsShrinking)
-
{
-
int delta = mOrientation == VERTICAL ? mContentHeight
-
: mContentWidth;
-
if (mPosition == LEFT || mPosition == TOP)
-
{
-
delta = -delta;
-
}
-
if (mOrientation == VERTICAL)
-
{
-
canvas.translate(0, delta);
-
}
-
else
-
{
-
canvas.translate(delta, 0);
-
}
-
}
-
if (mState == State.TRACKING || mState == State.FLYING
-
|| mState == State.CLICK)
-
{
-
canvas.translate(mTrackX, mTrackY);
-
}
-
super.dispatchDraw(canvas);
-
}
-
-
private float ensureRange(float v, int min, int max)
-
{
-
v = Math.max(v, min);
-
v = Math.min(v, max);
-
return v;
-
}
-
-
OnTouchListener touchListener = new OnTouchListener()
-
{
-
-
public boolean onTouch(View v, MotionEvent event)
-
{
-
-
if (mAnimating)
-
{
-
-
return true;
-
}
-
-
int action = event.getAction();
-
if (action == MotionEvent.ACTION_DOWN)
-
{
-
if (mBringToFront)
-
{
-
bringToFront();
-
}
-
}
-
-
if (!mGestureDetector.onTouchEvent(event))
-
{
-
if (action == MotionEvent.ACTION_UP)
-
{
-
-
-
long now = SystemClock.uptimeMillis();
-
mAnimationLastTime = now;
-
mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
-
mAnimating = true;
-
mHandler.removeMessages(MSG_ANIMATE);
-
mHandler.removeMessages(MSG_PREPARE_ANIMATE);
-
mHandler.sendMessageAtTime(
-
mHandler.obtainMessage(MSG_PREPARE_ANIMATE),
-
mCurrentAnimationTime);
-
}
-
}
-
return false;
-
}
-
};
-
-
public boolean initChange()
-
{
-
if (mState != State.READY)
-
{
-
-
return false;
-
}
-
mState = State.ABOUT_TO_ANIMATE;
-
mIsShrinking = mContent.getVisibility() == VISIBLE;
-
if (!mIsShrinking)
-
{
-
-
-
mContent.setVisibility(VISIBLE);
-
}
-
return true;
-
}
-
-
private void postProcess()
-
{
-
if (mIsShrinking && mClosedHandle != null)
-
{
-
mHandle.setBackgroundDrawable(mClosedHandle);
-
}
-
else if (!mIsShrinking && mOpenedHandle != null)
-
{
-
mHandle.setBackgroundDrawable(mOpenedHandle);
-
}
-
-
if (panelListener != null)
-
{
-
if (mIsShrinking)
-
{
-
panelListener.onPanelClosed(Panel.this);
-
}
-
else
-
{
-
panelListener.onPanelOpened(Panel.this);
-
}
-
}
-
}
-
-
class PanelOnGestureListener implements OnGestureListener
-
{
-
float scrollY;
-
float scrollX;
-
-
@Override
-
public boolean onDown(MotionEvent e)
-
{
-
scrollX = scrollY = 0;
-
lastRawX = curRawX = lastRawY = curRawY = -1;
-
lastEventTime = curEventTime = -1;
-
initChange();
-
return true;
-
}
-
-
@Override
-
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-
float velocityY)
-
{
-
mState = State.FLYING;
-
-
float velocityX2, velocityY2;
-
if (lastRawX == -1 && lastRawY == -1)
-
{
-
velocityX2 = (curRawX - e1.getRawX())
-
/ (curEventTime - e1.getEventTime()) * 1000;
-
velocityY2 = (curRawY - e1.getRawY())
-
/ (curEventTime - e1.getEventTime()) * 1000;
-
}
-
else
-
{
-
velocityX2 = (curRawX - lastRawX)
-
/ (curEventTime - lastEventTime) * 1000;
-
velocityY2 = (curRawY - lastRawY)
-
/ (curEventTime - lastEventTime) * 1000;
-
}
-
-
mVelocity = mOrientation == VERTICAL ? velocityY2 : velocityX2;
-
-
if (Math.abs(mVelocity) > 50)
-
{
-
if (mVelocity > 0)
-
{
-
mAnimatedAcceleration = mMaximumAcceleration;
-
}
-
else
-
{
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
}
-
-
long now = SystemClock.uptimeMillis();
-
mAnimationLastTime = now;
-
mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
-
mAnimating = true;
-
mHandler.removeMessages(MSG_ANIMATE);
-
mHandler.removeMessages(MSG_PREPARE_ANIMATE);
-
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
-
mCurrentAnimationTime);
-
return true;
-
}
-
return false;
-
}
-
-
@Override
-
public void onLongPress(MotionEvent e)
-
{
-
-
}
-
-
@Override
-
public boolean onScroll(MotionEvent e1, MotionEvent e2,
-
float distanceX, float distanceY)
-
{
-
mState = State.TRACKING;
-
float tmpY = 0, tmpX = 0;
-
if (mOrientation == VERTICAL)
-
{
-
scrollY -= distanceY;
-
if (mPosition == TOP)
-
{
-
tmpY = ensureRange(scrollY, -mContentHeight, 0);
-
}
-
else
-
{
-
tmpY = ensureRange(scrollY, 0, mContentHeight);
-
}
-
}
-
else
-
{
-
scrollX -= distanceX;
-
if (mPosition == LEFT)
-
{
-
tmpX = ensureRange(scrollX, -mContentWidth, 0);
-
}
-
else
-
{
-
tmpX = ensureRange(scrollX, 0, mContentWidth);
-
}
-
}
-
-
if (tmpX != mTrackX || tmpY != mTrackY)
-
{
-
mTrackX = tmpX;
-
mTrackY = tmpY;
-
-
}
-
invalidate();
-
-
lastRawX = curRawX;
-
lastRawY = curRawY;
-
lastEventTime = curEventTime;
-
curRawX = e2.getRawX();
-
curRawY = e2.getRawY();
-
curEventTime = e2.getEventTime();
-
return true;
-
}
-
-
@Override
-
public void onShowPress(MotionEvent e)
-
{
-
-
}
-
-
@Override
-
public boolean onSingleTapUp(MotionEvent e)
-
{
-
-
return false;
-
}
-
}
-
-
private void prepareAnimation()
-
{
-
-
switch (mPosition)
-
{
-
case LEFT:
-
if (mIsShrinking)
-
{
-
mVelocity = -mMaximumMajorVelocity;
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
-
}
-
else
-
{
-
mVelocity = mMaximumMajorVelocity;
-
mAnimatedAcceleration = mMaximumAcceleration;
-
if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE)
-
{
-
mTrackX = -mContentWidth;
-
}
-
}
-
break;
-
case RIGHT:
-
if (mIsShrinking)
-
{
-
mVelocity = mMaximumMajorVelocity;
-
mAnimatedAcceleration = mMaximumAcceleration;
-
}
-
else
-
{
-
mVelocity = -mMaximumMajorVelocity;
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
-
if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE)
-
{
-
mTrackX = mContentWidth;
-
}
-
}
-
break;
-
case TOP:
-
if (mIsShrinking)
-
{
-
mVelocity = -mMaximumMajorVelocity;
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
}
-
else
-
{
-
mVelocity = mMaximumMajorVelocity;
-
mAnimatedAcceleration = mMaximumAcceleration;
-
-
if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE)
-
{
-
mTrackY = -mContentHeight;
-
}
-
}
-
break;
-
case BOTTOM:
-
if (mIsShrinking)
-
{
-
mVelocity = mMaximumMajorVelocity;
-
mAnimatedAcceleration = mMaximumAcceleration;
-
}
-
else
-
{
-
mVelocity = -mMaximumMajorVelocity;
-
mAnimatedAcceleration = -mMaximumAcceleration;
-
-
if (mTrackX == 0 && mState == State.ABOUT_TO_ANIMATE)
-
{
-
mTrackY = mContentHeight;
-
}
-
}
-
break;
-
}
-
-
if (mState == State.TRACKING)
-
{
-
if (mIsShrinking)
-
{
-
if ((mOrientation == VERTICAL && Math.abs(mTrackY) < mContentHeight / 2)
-
|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) < mContentWidth / 2))
-
{
-
mVelocity = -mVelocity;
-
mAnimatedAcceleration = -mAnimatedAcceleration;
-
mIsShrinking = !mIsShrinking;
-
}
-
}
-
else
-
{
-
if ((mOrientation == VERTICAL && Math.abs(mTrackY) > mContentHeight / 2)
-
|| (mOrientation == HORIZONTAL && Math.abs(mTrackX) > mContentWidth / 2))
-
{
-
mVelocity = -mVelocity;
-
mAnimatedAcceleration = -mAnimatedAcceleration;
-
mIsShrinking = !mIsShrinking;
-
}
-
}
-
}
-
if (mState != State.FLYING && mState != State.TRACKING)
-
{
-
mState = State.CLICK;
-
}
-
}
-
-
private void doAnimation()
-
{
-
-
if (mAnimating)
-
{
-
long now = SystemClock.uptimeMillis();
-
float t = (now - mAnimationLastTime) / 1000.0f;
-
final float v = mVelocity;
-
final float a = mAnimatedAcceleration;
-
mVelocity = v + (a * t);
-
mAnimationLastTime = now;
-
-
switch (mPosition)
-
{
-
case LEFT:
-
mTrackX = mTrackX + (v * t) + (0.5f * a * t * t);
-
if (mTrackX > 0)
-
{
-
mTrackX = 0;
-
mState = State.READY;
-
mAnimating = false;
-
}
-
else if (mTrackX < -mContentWidth)
-
{
-
mTrackX = -mContentWidth;
-
mContent.setVisibility(GONE);
-
mState = State.READY;
-
mAnimating = false;
-
}
-
break;
-
case RIGHT:
-
mTrackX = mTrackX + (v * t) + (0.5f * a * t * t);
-
if (mTrackX < 0)
-
{
-
mTrackX = 0;
-
mState = State.READY;
-
mAnimating = false;
-
}
-
else if (mTrackX > mContentWidth)
-
{
-
mTrackX = mContentWidth;
-
mContent.setVisibility(GONE);
-
mState = State.READY;
-
mAnimating = false;
-
}
-
break;
-
case TOP:
-
mTrackY = mTrackY + (v * t) + (0.5f * a * t * t);
-
if (mTrackY > 0)
-
{
-
mTrackY = 0;
-
mState = State.READY;
-
mAnimating = false;
-
}
-
else if (mTrackY < -mContentHeight)
-
{
-
mTrackY = -mContentHeight;
-
mContent.setVisibility(GONE);
-
mState = State.READY;
-
mAnimating = false;
-
}
-
break;
-
case BOTTOM:
-
mTrackY = mTrackY + (v * t) + (0.5f * a * t * t);
-
if (mTrackY < 0)
-
{
-
mTrackY = 0;
-
mState = State.READY;
-
mAnimating = false;
-
}
-
else if (mTrackY > mContentHeight)
-
{
-
mTrackY = mContentHeight;
-
mContent.setVisibility(GONE);
-
mState = State.READY;
-
mAnimating = false;
-
}
-
break;
-
}
-
invalidate();
-
-
if (!mAnimating)
-
{
-
postProcess();
-
return;
-
}
-
mCurrentAnimationTime += ANIMATION_FRAME_DURATION;
-
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
-
mCurrentAnimationTime);
-
-
}
-
}
-
-
private class SlidingHandler extends Handler
-
{
-
public void handleMessage(Message m)
-
{
-
switch (m.what)
-
{
-
case MSG_ANIMATE:
-
doAnimation();
-
break;
-
case MSG_PREPARE_ANIMATE:
-
prepareAnimation();
-
doAnimation();
-
break;
-
}
-
}
-
}
-
}
http://blog.csdn.net/lovehong0306
工程下载地址:
http://download.csdn.net/detail/lovehong0306/4230052
android-misc-widgets多方抽屉bug修复版 解决“闪烁”问题
标签:des android style blog http io ar color os
原文地址:http://blog.csdn.net/lsong89/article/details/41345823