直接上效果图
记录仿写滴答清单App 过程中的技术点
本文分为以下章节,读者可按需阅读:
1.自定义RecycleItemTouchHelper
2.实现滴答清单左滑右滑效果
3.RecycleView使用自定义RecycleItemTouchHelper
一、ItemTouchHelper使用
本章介绍下ItemTouchHelper的基本使用方法,主要是我们后面实现左滑右滑会用到的类和方法,拖拽方法暂时不详细描述。
1.自定义RecycleItemTouchHelper类继承 ItemTouchHelper.Callback
public class RecycleItemTouchHelper extends ItemTouchHelper.Callback {
private static final String TAG = "RecycleItemTouchHelper";
private Resources resources;
private int padding;//灰色背景的宽度padding
private int linePadding;//对勾的宽度
// int maxDrawWidth=2*padding+bitmap.getWidth();//最大的绘制宽度
//背景画笔
private Paint paint;
private Paint mPaintTick;
//记录打钩路径的三个点坐标
private float[] mPoints = new float[8];
private ItemTouchHelperCallback helperCallback;
public RecycleItemTouchHelper(ItemTouchHelperCallback helperCallback) {
this.helperCallback = helperCallback;
resources = TodoApplication.getInstance().getResources();
padding = UiUtil.dip2px(TodoApplication.getInstance(), 60);//图片绘制的padding
linePadding = UiUtil.dip2px(TodoApplication.getInstance(), 16);//图片绘制的padding
//背景画笔
paint = new Paint();
mPaintTick = new Paint();
//对勾画笔
mPaintTick.setColor(resources.getColor(R.color.white));
mPaintTick.setStrokeCap(Paint.Cap.ROUND);
mPaintTick.setStrokeWidth(UiUtil.dip2px(TodoApplication.getInstance(), 2.4f));
}
/**
* 设置滑动类型标记
*
* @param recyclerView
* @param viewHolder
* @return 返回一个整数类型的标识,用于判断Item那种移动行为是允许的
*/
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//START 右向左 END左向右 LEFT 向左 RIGHT向右 UP向上
//如果某个值传0,表示不触发该操作,次数设置支持上下拖拽,支持向右滑动
return makeMovementFlags(0, LEFT | RIGHT);
}
/**
* Item是否支持长按拖动
*
* @return true 支持长按操作
* false 不支持长按操作
*/
@Override
public boolean isLongPressDragEnabled() {
return super.isLongPressDragEnabled();
}
/**
* Item是否支持滑动
*
* @return true 支持滑动操作
* false 不支持滑动操作
*/
@Override
public boolean isItemViewSwipeEnabled() {
return super.isItemViewSwipeEnabled();
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
switch (direction) {
case LEFT:
//左滑
helperCallback.onItemL(viewHolder.getAdapterPosition());
break;
case RIGHT:
//右滑
helperCallback.onItemR(viewHolder.getAdapterPosition());
break;
}
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
/**
* Item被选中时候回调
*
* @param viewHolder
* @param actionState 当前Item的状态
* ItemTouchHelper.ACTION_STATE_IDLE 闲置状态
* ItemTouchHelper.ACTION_STATE_SWIPE 滑动中状态
* ItemTouchHelper#ACTION_STATE_DRAG 拖拽中状态
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
}
//滑动接口回调
public interface ItemTouchHelperCallback {
void onItemR(int positon);
void onItemL(int positon);
}
}
复制代码2.实现滴答清单右滑效果
重写onChildDraw方法
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
//滑动时自己实现背景及图片
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
//dX大于0时向右滑动,小于0向左滑动
View itemView = viewHolder.itemView;//获取滑动的view
int x = Math.round(Math.abs(dX));
//1.向右滑动
if (dX > 0) {
if (x > padding) {
//滑动距离大于padding时开始变色
paint.setColor(resources.getColor(R.color.bg_completed));
} else {
//滑动距离小于padding时是灰色
paint.setColor(resources.getColor(R.color.todo));
}
//2.根据滑动实时绘制一个背景
c.drawRect(itemView.getLeft(), itemView.getTop(), x, itemView.getBottom(), paint);
//3.绘制对勾
//指定对勾绘制的位置,一个对勾需要三个点
//每一项的高
int h = itemView.getBottom() - itemView.getTop();
mPoints[0] = x - ((padding / 2) + (linePadding / 2));
mPoints[1] = itemView.getTop() + h / 2;
mPoints[2] = x - padding / 2;
mPoints[3] = itemView.getTop() + (h / 2 + linePadding / 2);
mPoints[4] = x - padding / 2;
mPoints[5] = itemView.getTop() + (h / 2 + linePadding / 2);
mPoints[6] = (float) (x - linePadding);
mPoints[7] = itemView.getTop() + (h / 2 - linePadding /2);
c.drawLines(mPoints, mPaintTick);
//绘制时需调用平移动画,否则滑动看不到反馈
itemView.setTranslationX(dX);
} else {
//左滑效果和右滑一样,暂未实现。
paint.setColor(resources.getColor(R.color.bg_todo));
c.drawRect(itemView.getRight(), itemView.getTop(), itemView.getWidth() - x, itemView.getBottom(), paint);
//绘制时需调用平移动画,否则滑动看不到反馈
itemView.setTranslationX(dX);
}
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
复制代码3.RecycleView使用自定义RecycleItemTouchHelper
ItemTouchHelper.Callback callback = new RecycleItemTouchHelper(todoAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerview);
复制代码
未完待续