Android仿滴答清单左滑右滑效果

2,034 阅读3分钟

直接上效果图

记录仿写滴答清单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);

未完待续