Android控件使用篇Android专题UI

Recycler进阶之路:ItemTouchHelper实现It

2020-11-16  本文已影响0人  千夜零一

引言

  RecyclerView系列我们已经实现了自定义分割线,还有自定义时间轴效果,它的强大功能可不止于此!今天又是玩转Recycler的一天,就来实现RecyclerView的侧滑删除和拖动排序效果。



介绍

  ItemTouchHelper,它是一个可以给RecyclerView提供添加拖动排序与滑动删除等等操作的工具类。RecyclerView的Item操作,离不开这个强大的工具类,话不多说,一起来看看怎么使用吧!


用法

第一步:创建接口:IOperationData

功能: 接口中定义两个实现方法:一个用来处理RecyclerView中多个Item的移动排序事件;一个用来处理Item的左滑删除事件。

/**
 * @data on 2020/11/13 5:49 PM
 * @auther armStrong
 * @describe ItemTouchHelper用法(RecyclerView拖拽、删除)
 */
public interface IOperationData {
    /**
     * 数据交换
     * @param fromPosition
     * @param toPosition
     */
    void onItemMove(int fromPosition,int toPosition);

    /**
     * 数据删除
     * @param position
     */
    void onItemDissmiss(int position);
}

第二步:创建回调类:IHCallback

功能: 需要继承ItemTouchHelper.Callback方法,重写Item的众多操作事件:滑动、按压弹起、移动。实现排序布局+滑动删除的主要类。

/**
 * @data on 2020/11/13 6:07 PM
 * @auther armStrong
 * @describe ItemTouchHelper用法(RecyclerView拖拽、删除)
 */
public class IHCallback extends ItemTouchHelper.Callback {

    private MoveAdapter moveAdapter;

    public IHCallback(MoveAdapter moveAdapter) {
        this.moveAdapter = moveAdapter;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        //允许上下的拖动
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //只允许从右向左侧滑
        int swipeFlags = ItemTouchHelper.LEFT;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        moveAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        moveAdapter.onItemDissmiss(viewHolder.getAdapterPosition());//调用我们自定义的方法
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            //滑动时改变Item的透明度
            final float alpha = 1 - Math.abs(dX) / (float)viewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);
        }
    }
}

第三步:创建Adapter类:MoveAdapter

功能:填充数据,并且实现接口中定义的两个方法:Item移动排序+滑动删除

/**
 * @data on 2020/11/13 5:55 PM
 * @auther armStrong
 * @describe  ItemTouchHelper用法(RecyclerView拖拽、删除)
 */
public class MoveAdapter extends RecyclerView.Adapter<MoveAdapter.MoveHolder> implements IOperationData {

    private List<String> mDataList;
    private LayoutInflater mInflater;
    private Context mContext;

    public MoveAdapter(Context context) {
        this.mContext = context;
        mInflater =LayoutInflater.from(mContext);
    }

    MoveAdapter(List<String> dataList) {
        mDataList = dataList;
    }

    public void setData(List<String> dataList) {
        mDataList = dataList;
        notifyDataSetChanged();
    }

    @Override
    public MoveHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        return new MoveHolder(mInflater.inflate(R.layout.item_move, parent, false));
    }

    @Override
    public void onBindViewHolder(MoveHolder holder, int position) {
        holder.mTextTitle.setText(mDataList.get(position));
    }

    @Override
    public int getItemCount() {
        return mDataList == null ? 0 : mDataList.size();
    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        //交换位置
        Collections.swap(mDataList,fromPosition,toPosition);
        notifyItemMoved(fromPosition,toPosition);

    }

    @Override
    public void onItemDissmiss(int position) {
        //移除数据
        mDataList.remove(position);
        notifyItemRemoved(position);
    }

    static class MoveHolder extends RecyclerView.ViewHolder {

        TextView mTextTitle;

        MoveHolder(View itemView) {
            super(itemView);
            mTextTitle = itemView.findViewById(R.id.tv_move);
        }
    }

}

第四步:布局文件

主布局:简单写一个TitleBar和一个RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".blog2.Case64"
    tools:ignore="MissingConstraints">
    <TextView
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="ItemTouchHelper用法(RecyclerView拖拽、删除)"
        android:textSize="16sp"
        android:textColor="@color/white"
        android:background="@color/black"
        android:gravity="center"
        />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler64"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
子布局:RecyclerView的item布局,简单写一个TextView
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/tv_move"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="测试一下"
        android:textSize="25sp"
        android:gravity="center"
        android:textColor="@color/black"
        tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

第五步:在Activity中书写业务逻辑代码

public class Case64 extends AppCompatActivity {
    private MoveAdapter adapter;
    private LinearLayoutManager layoutManager;
    private RecyclerView recycler;
    private List<String> itemList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_case64);
        initView();
        initData();
        initRecycler();
    }
    private void initView(){
        recycler = findViewById(R.id.recycler64);
    }

    private void initData(){
        itemList = new ArrayList<>();
        itemList.add("hahhhha");
        itemList.add("aaaaaaa");
        itemList.add("bbbbbbb");
        itemList.add("cccccc");
        itemList.add("ddddd");
        itemList.add("hahhhha");
        itemList.add("aaaaaaa");
        itemList.add("bbbbbbb");
        itemList.add("cccccc");
        itemList.add("ddddd");
    }

    private void initRecycler(){
        //瀑布流布局
        adapter = new MoveAdapter(this);
        layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        recycler.setLayoutManager(layoutManager);
        recycler.setAdapter(adapter);
        adapter.setData(itemList);

        //拖拽、删除
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new IHCallback(adapter));
        itemTouchHelper.attachToRecyclerView(recycler);

        //装饰
        recycler.setItemAnimator(new DefaultItemAnimator());
        recycler.addItemDecoration(new DividerItemDecoration(this)); //item分割线
        recycler.addItemDecoration(new TimeLineItemDecoration(this)); //时间轴效果
    }
}

  如果你想了解我的RecyclerView分割线,以及时间轴的自定义效果,不妨关注我的Android控件使用安利篇,偷偷告诉你,里面还有很多有趣控件哦!

此外,提供传送门送你直达:(本篇使用到的分割线+时间轴效果)
===>>>DividerItemDecoration():RecyclerView使用ItemDecoration实现好看的自定义分割线样式
===>>>TimeLineItemDecoration():RecyclerView之实现滚动时间轴效果


大功告成!

上一篇下一篇

猜你喜欢

热点阅读