RecycleView的Item拖拽效果以及拖拽位置保存

基于公司产品的优化需求,其中一个需求涉及到RecycleView的拖拽,以及拖拽后item位置的持久化,目的是可以用户自定义界面偏好,并在用户下次进入本界面后,之前设置的偏好仍然有效。我写了一个小Demo用作演示效果。

先看效果(只看效果,不看颜值)

 

步骤1、建接口文件ItemTouchHelperViewHolder,该接口文件中描述的是选中和放开当前Item调用的方法。

public interface ItemTouchHelperViewHolder {
    void onItemSelected(); //选中item
    void onItemCleared();//放开item
}

步骤2、写Item得ViewHolder的类,该类需要继承RecyclerView.ViewHolder类,同时要实现步骤中的接口。

public class ItemViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {

    private TextView tvName;

    public TextView getTvName() {
        return tvName;
    }

    public void setTvName(TextView tvName) {
        this.tvName = tvName;
    }

    public ItemViewHolder(@NonNull View itemView) {
        super(itemView);
        tvName = itemView.findViewById(R.id.tv_item_name);
    }

    @Override
    public void onItemSelected() {
        tvName.setBackgroundColor(Color.GRAY);
    }

    @Override
    public void onItemCleared() {
        tvName.setBackgroundColor(Color.YELLOW);}
}

步骤3、建立接口文件ItemTouchHelperAdapter,该文件中描写的是移动RecycleView的Item时会调用的方法。

public interface ItemTouchHelperAdapter {
    void onItemMove(int fromPosition,int toPosition);
}

步骤4、实现一个适配器,继承RecyclerView.Adapter<ItemViewHolder>,同时实现步骤3的接口。

public class RecyclerGridAdapter extends RecyclerView.Adapter<ItemViewHolder> implements ItemTouchHelperAdapter {
    private ArrayList<String> localDataSet;
    private SharedPreferences sp;
    private SharedPreferences.Editor spEditor;
    final static  String SAVE_KEY = "star_sort";
    final static String USER_PREFERENCE = "user_preference";
    private Context context;

    public RecyclerGridAdapter(ArrayList<String> dataSet,Context context) {
        String defaultStr = dataSet.toString();
        if(context != null){
            this.context = context;
            sp = context.getSharedPreferences(USER_PREFERENCE,Context.MODE_PRIVATE);
            spEditor = sp.edit();
            String saveString = sp.getString(SAVE_KEY,defaultStr);
            //考虑,若要更改数据源,需要怎么实现 todo
            String[] splitStr = saveString.replace("[","").replace("]","").replace(" ","").split(",");
            localDataSet = new ArrayList();
            localDataSet.addAll(Arrays.asList(splitStr));
        }
    }


    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_holder_layout, parent, false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
        holder.getTvName().setText(localDataSet.get(position));
    }

    @Override
    public int getItemCount() {
        return localDataSet.size();
    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        String prve = localDataSet.remove(fromPosition);
        if((toPosition > fromPosition) && (localDataSet.size() <= toPosition)){
            //将当前item移至最后一位
            localDataSet.add(prve);
        }else{
            localDataSet.add(toPosition, prve);
        }
        notifyItemMoved(fromPosition, toPosition);
        spEditor.putString(SAVE_KEY,localDataSet.toString());
        spEditor.apply();
    }
}

步骤5、实现ItemTouchHelper.Callback接口,至于什么是ItemTouchHelper,网上一查很多解释,我这不做阐述了。

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private ItemTouchHelperAdapter adapter;

    public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
        this.adapter = adapter;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, dragFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            return false;
        }
        adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {

    }


    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
            ItemTouchHelperViewHolder itemTouchHelperViewHolder = (ItemTouchHelperViewHolder) viewHolder;
            itemTouchHelperViewHolder.onItemSelected();
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        ItemViewHolder itemViewHolder = (ItemViewHolder) viewHolder;
        itemViewHolder.onItemCleared();
    }
}

步骤6,现在就可以调用啦,基于步骤5实现的ItemToucherHelper.Callback实例构建ItemTouchHelper实例,然后attach给RecycleView就好啦。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        with(viewBinding){
            var data = ArrayList<String>()
            var index = 10
            while (index-- >0){
                data.add(index.toString())
            }
            var adapter = RecyclerGridAdapter(data,this@MainActivity)
            recycleTest.layoutManager = GridLayoutManager(this@MainActivity,4)
            recycleTest.adapter = adapter
            var callback = SimpleItemTouchHelperCallback(adapter)
            var itemTouchHelper = ItemTouchHelper(callback)
            itemTouchHelper.attachToRecyclerView(recycleTest)
        }
    }
}

        就好啦,甘甘丹丹,整挺好。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要实现两个 RecyclerViewItem 相互拖拽,需要使用 ItemTouchHelper 类。具体步骤如下: 1. 在每个 RecyclerView 上设置 ItemTouchHelper.Callback。在这个回调中,实现 onMove 和 onSwiped 方法,分别用于处理拖拽和滑动删除事件。 2. 在 onMove 方法中,获取被拖拽Item位置和目标位置,并将它们交换。然后调用 RecyclerView.Adapter 的 notifyItemMoved 方法刷新显示。 3. 在 onSwiped 方法中,处理滑动删除事件。 4. 在 RecyclerView 上设置 LayoutManager,以控制 Item 的布局。 5. 需要注意的是,两个 RecyclerView 都需要设置 ItemTouchHelper,以实现相互拖拽。 下面是一个简单的实现示例: ``` ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() { @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); mAdapter.swapItems(fromPosition, toPosition); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); mAdapter.removeItem(position); } }; ItemTouchHelper helper = new ItemTouchHelper(callback); helper.attachToRecyclerView(recyclerView1); helper.attachToRecyclerView(recyclerView2); ``` 在这个示例中,我们定义了一个 ItemTouchHelper.Callback,并在其中实现了 onMove 和 onSwiped 方法。然后,我们将它们分别设置到两个 RecyclerView 上,以实现相互拖拽

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值