由于项目上的需要侧滑条目展示收藏按钮,记得之前代码家有写过一个厉害的开源控件 AndroIDSwipeLayout 本来准备直接拿来使用,但是看过 issue 发现现在有不少使用者反应有不少的 BUG,而且代码家现在貌似也不进行维护了.故自己实现了一个所要效果的一个控件.因为只是实现我需要的效果,所以大家也能看到,代码里有不少地方我是写死的.希望对大家有些帮助.而且暂时也不需要 AndroIDSwipeLayout 大而全的功能,算是变相给自己做的项目精简代码了.
完整示例代码请看:GitHub 地址
主要源码:
public class SwipeLayout extends FrameLayout {public static final int CLOSE = 0;public static final int OPEN = 1;private int mState = CLOSE;private int mWIDth;private int mHeight;private float mDownX;private float mDownY;private SwipeListener mSwipeListener;private VIEw mtopVIEw;private VIEw mBottomVIEw;private VIEwDragHelper mVIEwDragHelper;public SwipeLayout(Context context) {this(context,null);}public SwipeLayout(Context context,AttributeSet attrs) {this(context,attrs,0);}public SwipeLayout(Context context,AttributeSet attrs,int defStyleAttr) {super(context,defStyleAttr);mVIEwDragHelper = VIEwDragHelper.create(this,new VIEwDragHelper.Callback() {@OverrIDepublic boolean tryCaptureVIEw(VIEw child,int pointerID) {//只对mtopVIEw进行处理return child == mtopVIEw;}@OverrIDepublic int clampVIEwpositionHorizontal(VIEw child,int left,int dx) {//设置横向滑动的边界(left的值是mtopVIEw左上角点的x坐标值)int newleft;if (left <= -mBottomVIEw.getMeasureDWIDth()) {newleft = -mBottomVIEw.getMeasureDWIDth();} else if (left >= 0) {newleft = 0;} else {newleft = left;}return newleft;}@OverrIDepublic int clampVIEwpositionVertical(VIEw child,int top,int dy) {//因为不需要上下的滑动直接设置为0(top的值是mtopVIEw左上角点的y坐标值)return 0;}@OverrIDepublic voID onVIEwReleased(VIEw releasedChild,float xvel,float yvel) {//手指松开时会回调该函数int right = mWIDth - releasedChild.getRight();//mtopVIEw右边界距离屏幕右边的距离int bottomWIDth = mBottomVIEw.getMeasureDWIDth();if (right > bottomWIDth * 9 / 10) {scrollToleftEdge();return;}if (right <= bottomWIDth / 10 && right > 0) {scrollToRightEdge();return;}if (xvel == 0) {//速度为0时单独处理if (right >= bottomWIDth / 2) {scrollToleftEdge();} else if (right < bottomWIDth / 2) {scrollToRightEdge();}return;}if (xvel > 0) {//向右滑动后松手scrollToRightEdge();} else {//向左滑动后松手scrollToleftEdge();}}});}@OverrIDepublic voID computeScroll() {if (mVIEwDragHelper.continueSettling(true)) {invalIDate();}}@OverrIDepublic boolean onIntercepttouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:mDownX = ev.getRawX();mDownY = ev.getRawY();if (mState == CLOSE) {return true;}break;case MotionEvent.ACTION_MOVE:float distanceX = ev.getRawX() - mDownX;float distanceY = ev.getRawY() - mDownY;float angle;if (distanceX == 0) {angle = 90;} else {angle = (float) Math.todegrees(Math.atan(Math.abs(distanceY / distanceX)));}if (angle < 45) {return true;//拦截事件交给自己处理滑动}break;}return mVIEwDragHelper.shouldIntercepttouchEvent(ev);}@OverrIDepublic boolean ontouchEvent(MotionEvent ev) {VIEwParent vIEwParent = getParent();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:mDownX = ev.getRawX();mDownY = ev.getRawY();break;case MotionEvent.ACTION_MOVE:float distanceX = ev.getRawX() - mDownX;float distanceY = ev.getRawY() - mDownY;float angle;if (distanceX == 0) {angle = 90;} else {angle = (float) Math.todegrees(Math.atan(Math.abs(distanceY / distanceX)));}if (angle < 45 && vIEwParent != null) {vIEwParent.requestdisallowIntercepttouchEvent(true);//让父控件不要处理事件,交给子控件}break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if (vIEwParent != null) {vIEwParent.requestdisallowIntercepttouchEvent(false);}break;}mVIEwDragHelper.processtouchEvent(ev);return true;}@OverrIDeprotected voID onLayout(boolean changed,int l,int t,int r,int b) {super.onLayout(changed,l,t,r,b);int measureHeight = mBottomVIEw.getMeasuredHeight();int measureWIDth = mBottomVIEw.getMeasureDWIDth();mBottomVIEw.layout(mWIDth - measureWIDth,(mHeight - measureHeight) / 2,mWIDth,mHeight + measureHeight / 2);//靠右边界垂直居中if (mState == OPEN) {mtopVIEw.layout(-measureWIDth,mtopVIEw.getMeasureDWIDth() - measureWIDth,mtopVIEw.getMeasuredHeight());}}@OverrIDeprotected voID onSizeChanged(int w,int h,int olDW,int oldh) {super.onSizeChanged(w,h,olDW,oldh);mWIDth = w;mHeight = h;}@OverrIDeprotected voID onFinishInflate() {super.onFinishInflate();if (getChildCount() != 2) {throw new IllegalStateException("only and should contain two child vIEw");}VIEw bottomVIEw = getChildAt(0);if (!(bottomVIEw instanceof VIEwGroup)) {throw new IllegalStateException("sIDeslip menu should be contained by a vIEwgroup");}mBottomVIEw = bottomVIEw;mtopVIEw = getChildAt(1);}//回滚到左边(只能在onVIEwReleased里使用该方法)private voID scrollToleftEdge() {mVIEwDragHelper.settleCapturedVIEwAt(-mBottomVIEw.getMeasureDWIDth(),0);invalIDate();mState = OPEN;if (mSwipeListener != null) {mSwipeListener.onopenListener(this);}}//回滚到右边(只能在onVIEwReleased里使用该方法)private voID scrollToRightEdge() {mVIEwDragHelper.settleCapturedVIEwAt(0,0);invalIDate();mState = CLOSE;}public voID smoothClose() {mVIEwDragHelper.smoothSlIDeVIEwTo(mtopVIEw,0);invalIDate();mState = CLOSE;}public int getState() {return mState;}public voID setState(int state) {mState = state;invalIDate();}public interface SwipeListener {voID onopenListener(SwipeLayout swipeLayout);}public voID setSwipeListener(SwipeListener mSwipeListener) {this.mSwipeListener = mSwipeListener;}}
效果图
以上所述是小编给大家介绍的AndroID 中 SwipeLayout一个展示条目底层菜单的侧滑控件源码解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android 中 SwipeLayout一个展示条目底层菜单的侧滑控件源码解析全部内容,希望文章能够帮你解决Android 中 SwipeLayout一个展示条目底层菜单的侧滑控件源码解析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)