Android RecycleView實(shí)現(xiàn)Item拖拽效果
基于公司產(chǎn)品的優(yōu)化需求,其中一個(gè)需求涉及到RecycleView的拖拽,以及拖拽后item位置的持久化,目的是可以用戶自定義界面偏好,并在用戶下次進(jìn)入本界面后,之前設(shè)置的偏好仍然有效。我寫(xiě)了一個(gè)小Demo用作演示效果。
先看效果(只看效果,不看顏值)
步驟1、建接口文件ItemTouchHelperViewHolder,該接口文件中描述的是選中和放開(kāi)當(dāng)前Item調(diào)用的方法。
public interface ItemTouchHelperViewHolder { void onItemSelected(); //選中item void onItemCleared();//放開(kāi)item }
步驟2、寫(xiě)Item得ViewHolder的類(lèi),該類(lèi)需要繼承RecyclerView.ViewHolder類(lèi),同時(shí)要實(shí)現(xiàn)步驟中的接口。
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,該文件中描寫(xiě)的是移動(dòng)RecycleView的Item時(shí)會(huì)調(diào)用的方法。
public interface ItemTouchHelperAdapter { void onItemMove(int fromPosition,int toPosition); }
步驟4、實(shí)現(xiàn)一個(gè)適配器,繼承RecyclerView.Adapter<ItemViewHolder>,同時(shí)實(shí)現(xiàn)步驟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); //考慮,若要更改數(shù)據(jù)源,需要怎么實(shí)現(xiàn) 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)){ //將當(dāng)前item移至最后一位 localDataSet.add(prve); }else{ localDataSet.add(toPosition, prve); } notifyItemMoved(fromPosition, toPosition); spEditor.putString(SAVE_KEY,localDataSet.toString()); spEditor.apply(); } }
步驟5、實(shí)現(xiàn)ItemTouchHelper.Callback接口,至于什么是ItemTouchHelper,網(wǎng)上一查很多解釋?zhuān)疫@不做闡述了。
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,現(xiàn)在就可以調(diào)用啦,基于步驟5實(shí)現(xiàn)的ItemToucherHelper.Callback實(shí)例構(gòu)建ItemTouchHelper實(shí)例,然后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實(shí)現(xiàn)Item拖拽效果的詳細(xì)內(nèi)容,更多關(guān)于Android RecycleView拖拽Item的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Android移動(dòng)開(kāi)發(fā)recycleView的頁(yè)面點(diǎn)擊跳轉(zhuǎn)設(shè)計(jì)實(shí)現(xiàn)
- Android使用NestedScrollView?內(nèi)嵌RecycleView滑動(dòng)沖突問(wèn)題解決
- Android RecycleView和線型布局制作聊天布局
- RecycleView實(shí)現(xiàn)各種尺寸圖片展示
- android RecycleView實(shí)現(xiàn)多級(jí)樹(shù)形列表
- Android開(kāi)發(fā)可添加頭尾的RecycleView的實(shí)現(xiàn)
相關(guān)文章
關(guān)于Android中ListView嵌套GridView的問(wèn)題
在Android開(kāi)發(fā)的過(guò)程中可能需要用到listview嵌套gridview的場(chǎng)景,但是在嵌套過(guò)程中也許會(huì)遇到問(wèn)題,我們下面一起來(lái)看看是什么問(wèn)題以及如何解決。2016-08-08Android中實(shí)現(xiàn)TCP和UDP傳輸實(shí)例
這篇文章主要介紹了Android中實(shí)現(xiàn)TCP和UDP傳輸實(shí)例,本文給出了TCP服務(wù)器端代碼、TCP客戶端代碼、UDP服務(wù)器端代碼、UDP客戶端代碼等代碼實(shí)例,需要的朋友可以參考下2015-03-03Android實(shí)現(xiàn)向Launcher添加快捷方式的方法
這篇文章主要介紹了Android實(shí)現(xiàn)向Launcher添加快捷方式的方法,涉及Android添加快捷方式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android獲取手機(jī)本機(jī)號(hào)碼的實(shí)現(xiàn)方法
這篇文章主要介紹了Android獲取手機(jī)本機(jī)號(hào)碼的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文大家能夠?qū)崿F(xiàn)這樣的方法,需要的朋友可以參考下2017-10-10解決Android Studio sdk emulator directory is missing問(wèn)題
這篇文章主要介紹了解決Android Studio sdk emulator directory is missing問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android自定義View實(shí)現(xiàn)抖音飄動(dòng)紅心效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)抖音飄動(dòng)紅心效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Android 自定義輸入支付密碼的軟鍵盤(pán)實(shí)例代碼
這篇文章主要介紹了Android 自定義輸入支付密碼的軟鍵盤(pán)實(shí)例代碼的相關(guān)資料,并附簡(jiǎn)單實(shí)例代碼和實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-11-11