仿微信侧滑ListView item滑动布局

现在微信和QQListView都有一个功能 item滑动出现滑动布局,效果如下:

      

今天就让我们自个来实现这个效果



一.自定义侧滑菜单:

我们通过分解,知道RecycleView的每个item其实都是一个侧滑菜单 所以我们首先需要实现自定义侧滑菜单,实现效果如下图:
       

其实实现这个效果也并不难,将其分解我们得出如下实现逻辑:
1.自定义view有两部分组成,主界面和侧滑菜单界面,明显应该继承自ViewGroup;
2.正常情况下侧滑菜单位于主界面右侧,因此我们需要对自定义view的child重写onLayout方法确定其位置
3.实现手势滑动效果,针对这个如果是在以前我们就会通过事件分发机制做一些列的处理。但今天我们使用ViewDragHelper实现这个效果。
废话不多说直接贴出自定义类的代码,然后我们在一步步的分析代码:
SwipeLayout.java
public class SwipeLayout extends FrameLayout{
    private ViewDragHelper mDragHelper;//滑动帮助类
    private int mScreenWidth;//屏幕宽度
    private int mStuate = CLOSE;//当前侧滑菜单状态
    private static final int OPEN = 1;
    private static final int CLOSE = 2;
    public SwipeLayout(Context context) {
        super(context);
        init(context);
    }
    public SwipeLayout(Context context, AttributeSet attrs){
        super(context, attrs);
        init(context);
    }
    public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr){
        super(context, attrs, defStyleAttr);
        init(context);
    }
    private void init(Context context){
        mDragHelper = ViewDragHelper.create(this,1.0f,new ViewDragHelperCallback());
        mScreenWidth = getScreenWidth(context);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b){
        super.onLayout(changed, l, t, r, b);
        View leftView = getLeftView();
        leftView.layout(mScreenWidth,leftView.getTop(),mScreenWidth + leftView.getWidth(),leftView.getBottom());
        View mainView = getMainView();
        mainView.layout(mainView.getLeft(),mainView.getTop(),mScreenWidth,mainView.getBottom());
    }
    private class ViewDragHelperCallback extends ViewDragHelper.Callback {
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return true;
        }
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            if (child == getMainView()){
                if (left > 0) {//左滑动 界面不能滚出屏幕
                    return 0;
                }
                if (left > -(getLeftView().getWidth() + getPaddingLeft())){//右划不能超过隐藏布局的宽度
                    return left;
                }
                return -getLeftView().getWidth() - getPaddingLeft();
            }else{
                if (left < mScreenWidth - getLeftView().getWidth() - getPaddingLeft()){
                    return mScreenWidth - getLeftView().getWidth() - getPaddingLeft();
                }
                return left;
            }
        }
        @Override
        public int getViewHorizontalDragRange(View child) {
            return getLeftView().getWidth() + getMainView().getWidth();
        }
        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            int left = getPaddingLeft();
            if (xvel > 0 || (xvel == 0 && mStuate == OPEN)) {
                mStuate = CLOSE;
                left = 0;
            } else{
                mStuate = OPEN;
                left -= getLeftView().getWidth();
            }
            mDragHelper.smoothSlideViewTo(getMainView(),left,releasedChild.getTop());
            invalidate();
        }
        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
            if (changedView == getMainView()){
                getLeftView().layout(mScreenWidth + left,getLeftView().getTop(),mScreenWidth + getLeftView().getWidth() + left,getLeftView().getBottom());
            }else{
                getMainView().offsetLeftAndRight(dx);
            }
        }
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mDragHelper.shouldInterceptTouchEvent(ev);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragHelper.processTouchEvent(event);
        return true;
    }
    @Override
    public void computeScroll()
    {
        if(mDragHelper.continueSettling(true))
        {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }
    private View getMainView(){
        if (getChildCount() == 0){
            return null;
        }
        return getChildAt(0);
    }
    private View getLeftView(){
        if (getChildCount() == 0 || getChildCount() ==1){
            return null;
        }
        return getChildAt(getChildCount() - 1);
    }
    public void open(){
        mDragHelper.smoothSlideViewTo(getMainView(),-getLeftView().getWidth()- getPaddingLeft(),getMainView().getTop());
        invalidate();
    }
    public void close(){
        mDragHelper.smoothSlideViewTo(getMainView(),-getLeftView().getWidth()- getPaddingLeft(),getMainView().getTop());
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值