前两天在微博上看到了这个侧滑删除的粒子效果,但是只有IOS的,所以心血来潮,写了个玩玩,下面简单介绍下实现的思路
项目简介
先不废话,上效果图
项目地址:https://github.com/ZhaoKaiQiang/ParticleLayout
实现原理解析
其实看了那么多的关于侧滑删除的项目,再来思考这个问题,就so easy了!
咱们先分析下需求:
- 侧滑手势检测
- 粒子跟手效果
- 删除状态判断
- 数据源刷新
ok,知道需求了,咱们看对策
- 手势检测可以重写onTouch,判断移动方向和距离
- 粒子效果使用第三方的开源项目leonids,跟手效果就是简单的触摸位置的更新
- 假定滑动距离超过item的宽度一半,就代表删除
- 添加回调接口,完成数据源刷新
代码实现
知道了咱们的需求,并且每一个需求都有了解决方案,那么剩下的问题其实就是如何写代码的问题了。
下面这部分,最好参考这个项目的源码进行阅读~
首先,这肯定是属于自定义控件,那么咱们继承谁呢?我选择继承FrameLayout,为啥呢?因为在FrameLayout里面咱们可以控制遮罩效果。
其实完成遮罩效果,也有两种方案,
- 在FrameLayout中放置一个和背景色相同的布局,然后再onTouch中控制宽度,来模拟遮罩效果
- 直接重写dispatchDraw(Canvas canvas) ,使用Canvas.clipRect()控制绘制区域,模拟遮罩效果
其实这两种效果我都做过,在第一个版本中使用的是方案一,可以完成这个效果,但是不知道怎么回事,在5.0以上系统中,遮罩层的层级关系和5.0以下不一致,因此导致在5.0以上不能使用。除此之外, 使用第一种效果需要多一层布局,效率低,而且通用性不好,所以在这里我选择第二种方案。
咱们开始看代码~
public ParticleLayout(Context context) {
this(context, null);
}
public ParticleLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ParticleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
backLayoutRect = new Rect();
backLocation = new int[2];
}
构造函数非常简单,在三个参数构造函数中,初始化两个变量,backLayoutRect用于控制内容区域,用于后面的触摸边界检测,backLocation则用于存储布局位置,粒子效果需要用坐标。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (getChildCount() != 1) {
throw new IllegalArgumentException("the count of child view must be one !");
}
backLayout = (ViewGroup) getChildAt(0);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
backLayout.getLocationInWindow(backLocation);
backLayoutRect.se