安卓自定义控件之左滑删除


目标:

今天我们要做的效果图为:

Android左滑删除 android 左滑控件_ide

Android左滑删除 android 左滑控件_自定义_02

左滑之后会有删除按钮。上面这个图,为了主要研究原理,我们就先只加删除按钮好了。

思路:

在实现这个功能的时候,看了些资料。主要有两种:

1、      将内容和按钮当做两个可操作的对象,然后通过DragViewHelper监听内容和按钮执行拖拽的操作方法。然后去重新onlayout他们的位置。

2、      将内容和按钮作为一个整体,通过scroller对象进行整体滑动。

今天我们选用方法2来进行处理。

 

代码分析

好的,我们开始吧。

布局:

Android左滑删除 android 左滑控件_ide_03



这里我们用的基布局为merge,merge继承自activity(厉害了!内部是个LinearLayout),id = view_content是我们之后要填充内容的地方,预留这个是希望将这个控件封装成一个基类使用。Id=holder就是我们的按钮。

遇到的问题:这里的基布局之前用的是LinearLayout,但是导致了一个很严重的问题,就是左滑的时候只有view_content在滑动,而holder并没有滑动出来,这里我的view_content中的内容用的是match_parent,view_content本身用的是wrap_content。这个问题应该是view在测绘的时候所导致的。具体哪一步我不太清楚。

然后我就讲基布局改为了Merge。

Merge查阅资料之后发现,他存在的目的是简化view树中的基节点。

例子:

Android左滑删除 android 左滑控件_自定义_04

其实他减少了一层布局结构。很有可能我的显示问题就是由于多了一层布局结构的测量时导致的。

Merge的使用注意:

1、<merge />只能作为XML布局的根标签使用

2、当Inflate以<merge/>开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoot为true。

 

SlideView对象代码:

接下来正式开始自定义的SlideView内部代码讲解:

对象和布局的初始化

Android左滑删除 android 左滑控件_ide_05

Android左滑删除 android 左滑控件_自定义_06

这里没什么好分析的,就是初始化对象和获取对象。这里我们定义了一个滑动监听对象,对滑动所带来的状态改变进行相应的监控。

Android左滑删除 android 左滑控件_android_07

因为我们在这里需要用到一个很重要的长度量就是删除按钮部分的长度。这是后期滑动长度的主要依据。

注意:这里我们只能获holder.getMeasuredWidth(),获取holder.getWidth()的值为0。因为onsizechange的生命周期在onMeasure之后,在onlayout之前。

这里面所得到的所有值的单位都是像素(px)。

点击事件处理:

基础的准备工作搞完,下面是正式的事件处理。

Android左滑删除 android 左滑控件_ide_08

Android左滑删除 android 左滑控件_android_09

Android左滑删除 android 左滑控件_ide_10

Android左滑删除 android 左滑控件_控件_11


万一在滑动过程中手势滑动出控件,这里的事件即不是move也不是up。所以我们需要额外处理。

自定义方法:

Android左滑删除 android 左滑控件_android_12



Android左滑删除 android 左滑控件_android_13



在手势操作之后我们基本上实现了滑动功能,这里我们给上我们自定义的方法,以便实现比较好的对象的复用。

 

总结:

Android左滑删除 android 左滑控件_android_14

1、      在方法1中我们用DragViewHelperD去实现,其实我们发现无论是context还是dragViewHelper我们都是检测的手势对象event,然后再通过event中手势的反馈去手动的操作对象。

dragViewHelper只是把event的事件的处理委托给他了。我在在他的回调方法中进行相应的处理

2、      事件传递机制,看了任玉刚,任大大的书之后还是有了比较好的理解。

Touch事件的传递在ontouchevent中进行拦截处理,因为move是一个连续但是会会随着移动不停出发的过程,如果希望后续的手势事件依然被处理,我们在move中返回true。但是up的时候记得要将状态置为false。

3、getScrollX();获取的是当前移动后的位置和原始位置的距离。记得向有为正方向