前几天项目需要用到左侧拉出抽屉,想到了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();?//放在此导致极快速滑动至touch区域外界面不刷新(mTrackX、mTrackY均为0)??
- ????????????}??
- ????????????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)???//见onScroll方法??
- ????????????{??
- ????????????????velocityX2?=?(curRawX?-?e1.getRawX())??
- ????????????????????????/?(curEventTime?-?e1.getEventTime())?*?1000;?//??px/s??
- ????????????????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方法代码如下:
?
- 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?<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;??
- ????????????????}??
- ????????????}??
- ????????}??
- ????????if?(mState?!=?State.FLYING?&&?mState?!=?State.TRACKING)??
- ????????{??
- ????????????mState?=?State.CLICK;??
- ????????}??
- ????}??
其中类似
- 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;??
- /**?
- ?*??
- ?*?Fixed?by?http://blog.csdn.net/lovehong0306/article/details/7451264?
- ?*??
- ?*/??
- 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;??
- ??
- ????/**?
- ?????*?Callback?invoked?when?the?panel?is?opened/closed.?
- ?????*/??
- ????public?static?interface?OnPanelListener??
- ????{??
- ????????/**?
- ?????????*?Invoked?when?the?panel?becomes?fully?closed.?
- ?????????*/??
- ????????public?void?onPanelClosed(Panel?panel);??
- ??
- ????????/**?
- ?????????*?Invoked?when?the?panel?becomes?fully?opened.?
- ?????????*/??
- ????????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);?????//?duration?defaults?to?750?ms??
- ????????mPosition?=?a.getInteger(R.styleable.Panel_position,?BOTTOM);???????????//?position?defaults?to?BOTTOM??
- ????????mLinearFlying?=?a.getBoolean(R.styleable.Panel_linearFlying,?false);????//?linearFlying?defaults?to?false??
- ????????mWeight?=?a.getFraction(R.styleable.Panel_weight,?0,?1,?0.0f);??????????//?weight?defaults?to?0.0??
- ????????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);??
- ??
- ????????//?i?DON'T?really?know?why?i?need?this...??
- ????????setBaselineAligned(false);??
- ????}??
- ??
- ????/**?
- ?????*?Sets?the?listener?that?receives?a?notification?when?the?panel?becomes?
- ?????*?open/close.?
- ?????*??
- [email protected]?
- ?????*????????????The?listener?to?be?notified?when?the?panel?is?opened/closed.?
- ?????*/??
- ????public?void?setOnPanelListener(OnPanelListener?onPanelListener)??
- ????{??
- ????????panelListener?=?onPanelListener;??
- ????}??
- ??
- ????/**?
- ?????*?Gets?Panel's?mHandle?
- ?????*??
- [email protected]'s?mHandle?
- ?????*/??
- ????public?View?getHandle()??
- ????{??
- ????????return?mHandle;??
- ????}??
- ??
- ????/**?
- ?????*?Gets?Panel's?mContent?
- ?????*??
- [email protected]'s?mContent?
- ?????*/??
- ????public?View?getContent()??
- ????{??
- ????????return?mContent;??
- ????}??
- ??
- ????/**?
- ?????*?Sets?the?acceleration?curve?for?panel's?animation.?
- ?????*??
- [email protected]?
- ?????*????????????The?interpolator?which?defines?the?acceleration?curve?
- ?????*/??
- ????public?void?setInterpolator(Interpolator?i)??
- ????{??
- ????????mInterpolator?=?i;??
- ????}??
- ??
- ????/**?
- ?????*?Set?the?opened?state?of?Panel.?
- ?????*??
- [email protected]?
- ?????*????????????True?if?Panel?is?to?be?opened,?false?if?Panel?is?to?be?closed.?
- [email protected]?
- ?????*????????????True?if?use?animation,?false?otherwise.?
- ?????*??
- [email protected],?false?otherwise.?
- ?????*??
- ?????*/??
- ????public?boolean?setOpen(boolean?open,?boolean?animate)??
- ????{??
- ????????if?(mState?==?State.READY?&&?isOpen()?^?open)??
- ????????{??
- ????????????mIsShrinking?=?!open;??
- ????????????if?(animate)??
- ????????????{??
- ????????????????mState?=?State.ABOUT_TO_ANIMATE;??
- ????????????????if?(!mIsShrinking)??
- ????????????????{??
- ????????????????????//?this?could?make?flicker?so?we?test?mState?in??
- ????????????????????//?dispatchDraw()??
- ????????????????????//?to?see?if?is?equal?to?ABOUT_TO_ANIMATE??
- ????????????????????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;??
- ????}??
- ??
- ????/**?
- ?????*?Returns?the?opened?status?for?Panel.?
- ?????*??
- [email protected],?false?otherwise.?
- ?????*/??
- ????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);??
- ????????//?mHandle.setOnClickListener(clickListener);??
- ??
- ????????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?+?"'");??
- ????????}??
- ??
- ????????//?reposition?children??
- ????????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)??
- ????{??
- ????????//?String?name?=?getResources().getResourceEntryName(getId());??
- ????????//?Log.d(TAG,?name?+?"?ispatchDraw?"?+?mState);??
- ????????//?this?is?why?'mState'?was?added:??
- ????????//?avoid?flicker?before?animation?start??
- ????????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)??
- ????????????{??
- ????????????????//?we?are?animating??
- ????????????????return?true;//?动画中不响应onTouch事件??
- ????????????}??
- ??
- ????????????int?action?=?event.getAction();??
- ????????????if?(action?==?MotionEvent.ACTION_DOWN)??
- ????????????{??
- ????????????????if?(mBringToFront)??
- ????????????????{??
- ????????????????????bringToFront();??
- ????????????????}??
- ????????????}??
- ??
- ????????????if?(!mGestureDetector.onTouchEvent(event))??
- ????????????{??
- ????????????????if?(action?==?MotionEvent.ACTION_UP)??
- ????????????????{??
- ????????????????????//?tup?up?after?scrolling??
- ??
- ????????????????????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)??
- ????????{??
- ????????????//?we?are?animating?or?just?about?to?animate??
- ????????????return?false;??
- ????????}??
- ????????mState?=?State.ABOUT_TO_ANIMATE;??
- ????????mIsShrinking?=?mContent.getVisibility()?==?VISIBLE;??
- ????????if?(!mIsShrinking)??
- ????????{??
- ????????????//?this?could?make?flicker?so?we?test?mState?in?dispatchDraw()??
- ????????????//?to?see?if?is?equal?to?ABOUT_TO_ANIMATE??
- ????????????mContent.setVisibility(VISIBLE);??
- ????????}??
- ????????return?true;??
- ????}??
- ??
- ????private?void?postProcess()??
- ????{??
- ????????if?(mIsShrinking?&&?mClosedHandle?!=?null)??
- ????????{??
- ????????????mHandle.setBackgroundDrawable(mClosedHandle);??
- ????????}??
- ????????else?if?(!mIsShrinking?&&?mOpenedHandle?!=?null)??
- ????????{??
- ????????????mHandle.setBackgroundDrawable(mOpenedHandle);??
- ????????}??
- ????????//?invoke?listener?if?any??
- ????????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)???//见onScroll方法??
- ????????????{??
- ????????????????velocityX2?=?(curRawX?-?e1.getRawX())??
- ????????????????????????/?(curEventTime?-?e1.getEventTime())?*?1000;?//??px/s??
- ????????????????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)??
- ????????{??
- ????????????//?not?used??
- ????????}??
- ??
- ????????@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();?//放在此导致极快速滑动至touch区域外界面不刷新(mTrackX、mTrackY均为0)??
- ????????????}??
- ????????????invalidate();??
- ??
- ????????????lastRawX?=?curRawX;??
- ????????????lastRawY?=?curRawY;??
- ????????????lastEventTime?=?curEventTime;??
- ????????????curRawX?=?e2.getRawX();??
- ????????????curRawY?=?e2.getRawY();??
- ????????????curEventTime?=?e2.getEventTime();??
- ????????????return?true;??
- ????????}??
- ??
- ????????@Override??
- ????????public?void?onShowPress(MotionEvent?e)??
- ????????{??
- ????????????//?not?used??
- ????????}??
- ??
- ????????@Override??
- ????????public?boolean?onSingleTapUp(MotionEvent?e)??
- ????????{??
- ????????????//?not?used??
- ????????????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;?????//?ms?->?s??
- ????????????final?float?v?=?mVelocity;??????????????????????????//?px/s??
- ????????????final?float?a?=?mAnimatedAcceleration;??????????????//?px/s/s??
- ????????????mVelocity?=?v?+?(a?*?t);????????????????????????????//?px/s??
- ????????????mAnimationLastTime?=?now;??
- ??
- ????????????switch?(mPosition)??
- ????????????{??
- ????????????????case?LEFT:??
- ????????????????????mTrackX?=?mTrackX?+?(v?*?t)?+?(0.5f?*?a?*?t?*?t);?//?px??
- ????????????????????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://download.csdn.net/detail/lovehong0306/4230052