| 方案 | 優點 | 缺點 | 推薦指數 |
|---|---|---|---|
| RecyclerView + ItemTouchHelper (官方) | 原生支援、效能最好、Material Design 風格、可自定義動畫 | 需理解 Callback 複雜 API | ⭐⭐⭐⭐⭐ |
第三方庫 SwipeMenuRecyclerView | API 簡單、效果豐富 (左滑菜單、彈性)、文檔完善 | 引入依賴、部分庫停止維護 | ⭐⭐⭐⭐ |
| 自定義 ViewGroup + 觸摸事件分發 | 完全可控、無依賴 | 開發成本高、邊界情況易出 bug | ⭐⭐ |
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
@Override
public boolean onMove(RecyclerView rv, ViewHolder vh, ViewHolder target) {
return false; // 不支援拖拽排序
}
@Override
public void onSwiped(ViewHolder vh, int direction) {
int pos = vh.getAdapterPosition();
// 1. 從資料源移除
dataList.remove(pos);
// 2. 通知適配器 (關鍵:使用 notifyItemRemoved 而非 notifyDataSetChanged)
adapter.notifyItemRemoved(pos);
// 3. 可選:Snackbar 提供撤銷
Snackbar.make(rv, "已刪除", Snackbar.LENGTH_LONG)
.setAction("撤銷", v -> {
dataList.add(pos, deletedItem);
adapter.notifyItemInserted(pos);
}).show();
}
@Override
public void onChildDraw(Canvas c, RecyclerView rv, ViewHolder vh, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// 自定義滑動時的背景/圖標繪製
View itemView = vh.itemView;
// 繪製紅色刪除背景
p.setColor(Color.RED);
c.drawRect(itemView.getRight() + dX, itemView.getTop(), itemView.getRight(), itemView.getBottom(), p);
// 繪製垃圾桶圖標
// ...
super.onChildDraw(c, rv, vh, dX, dY, actionState, isCurrentlyActive);
}
};
new ItemTouchHelper(callback).attachToRecyclerView(recyclerView);
// 1. Gradle 依賴
implementation 'com.github.yanzhenjie:recyclerview-swipe:1.1.5'
// 2. 建立菜單創建器
SwipeMenuCreator creator = (leftMenu, rightMenu, position) -> {
SwipeMenuItem deleteItem = new SwipeMenuItem(context)
.setBackground(R.color.red)
.setText("刪除")
.setTextColor(Color.WHITE)
.setWidth(180)
.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
rightMenu.addMenuItem(deleteItem); // 右側菜單 (左滑顯示)
};
// 3. 設置給 RecyclerView
SwipeMenuRecyclerView swipeMenuRecyclerView = findViewById(R.id.rv);
swipeMenuRecyclerView.setSwipeMenuCreator(creator);
swipeMenuRecyclerView.setSwipeItemClickListener((view, position, menuIndex) -> {
if (menuIndex == 0) { // 刪除按鈕
dataList.remove(position);
adapter.notifyItemRemoved(position);
}
});
使用 `SwipeMenuCreator` 添加多個 `SwipeMenuItem` 到 `rightMenu`,或 ItemTouchHelper 中 `onChildDraw` 繪製多個圖標區域並在 `onSwiped` 或自定義觸摸攔截中判斷點擊區域。