Listview侧滑删除思路浅析

自己最近也在看关于继承系统控件实现自定义控件的例子, ListView滑动删除实现之四——Scroller类与listview缓慢滑动,大家可以关注原文理解。这里我简单说一下自己对原文的理解。
1.实现侧滑的效果,可以在onTouchEvent()中的三个状态中进行处理

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int maxLength = dipToPx(mContext, MAX_WIDTH);

        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                //当前点击了哪一行
                int position = pointToPosition(x, y);

            break;
            case MotionEvent.ACTION_MOVE: {

            break;
            case MotionEvent.ACTION_UP: {

            break;
        }

        return super.onTouchEvent(event);
    }

2.这里大家要明白实现侧滑跟滑动一定距离自己滑动过去的动画效果区分开来。
实现滑动的方法是通过View的scrollTo(),是即时的

  itemView.scrollTo(scrollX, 0);
  /**scrollX代表的是itemView对于父View也就是Listview的左上角的X轴上的偏移量。当我按下一个item的时候,手指滑动一定的距离,这个时候scrollX的值就是两点之间x轴上的距离。*/
  ```
   int newScrollX = scrollX + mlastX - x;
   /**
   1.scrollX 上面已经说过
   2.mlastX  代表手指滑动中的某一个点的X轴坐标,每当执行一次滑动操作后都会对mlastX 重新赋值,这个值其实就是上一次滑动操作过程中的x
   3.x        当前手指的x方向的坐标,比mlastX总是提前一步
   */
  ``这样就可以得到一个等式,可以确定newScrollx的变化,从而调用`scrollTo()实现滑动,再次强调是瞬时的,一步到位。

滑动一段距离后,比如滑动超过100px后使用scroller类的startScroll()方法,滑动到指定位置,是一个缓慢的过程。

   mScroller.startScroll(scrollX, 0, newScrollX - scrollX, 0);
   /**
   1.scrollX   上面已经解释,就是已经相对于左上角滑动的距离
   2.newScrollX - scrollX 就是手指已经抬起了,使用scroller实现缓慢滑动效果需要滑动的距离
   */

原文博客中博主也提到了,虽然我们调用了startScroll(),但是并不能实现滑动效果,必须要scrollTo()才可以滑动,但是scrollTo()又是在哪里调用呢,什么时机调用呢?

 @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            itemRoot.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        }
        invalidate();

    }
    /**
1.computeScroll()方法是view的方法,每次调用了 invalidate(),都会执行此方法
2.computeScrollOffset()主要是为了判断滑动是否停止
3.重要的mScroller.getCurrX(),它就是获取到在动画效果执行的过程中通过mScroller计算出的分段目标的滑动距离
*/

不要忘记调用invalidate()!!!
说到这,可以实 现滑动了,删除的点击事件大家没问题。但是博主也提到了如此而来会有一个冲突的问题。我们不能很好的处理listview的各个itemView的滑动,尝试在 onTouchevent()中根据ACTION_UP的进行判断,发现处理的不及时。
这个时候装逼时刻来了,面向对象的思想。捂脸,捂脸。如果我们将listview的itemView封装成可滑动的,让他们自己去处理自己滑动收缩,而不是listview来处理。
但是,我们要告诉人家啥时候执行滑动收缩的操作,前提是itemView现在是完全打开的情况。这个时候可以给每个itemView设置一个收缩监听接口,定义一个收缩的抽象方法。当满足收缩条件的时候,调用方法。
itemView自己可以自己控制自己滑动跟收缩了,但是还要listView给自己这个机会呀,这里需要提到事件分发了。

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                //我们想知道当前点击了哪一行
                int position = pointToPosition(x, y);
                if (position != INVALID_POSITION) {
                    NewAdapter.DataHolder data = (NewAdapter.DataHolder) getItemAtPosition(position);
                    mCurView = data.rootView;
                }
            }
            break;
            default:
                break;
        }
        if (mCurView != null){
        //分发给itemView
            mCurView.disPatchTouchEvent(event);
        }
        return super.onTouchEvent(event);
    }
以上就是我对原博客的理解,请指正。倾盆~~~~~
顺带说一句,博客原来提到如果将属性设置为wrap_content 后会无法滑动,我后来重新测量了一下listview在onMeasure()中,是可以滑动的,大家可以测试一下。
第一次写博客,再次感谢原博主对我的帮助~~~~~~~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值