Android RecycleView实现Item拖拽效果
作者:爱吃烧鸡大肘子的肉肉酱
RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。本文将介绍通过RecyclerView实现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) } } }
以上就是Android RecycleView实现Item拖拽效果的详细内容,更多关于Android RecycleView拖拽Item的资料请关注脚本之家其它相关文章!