首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 實現 iOS 風格 TableViewCell 左滑刪除/編輯按鈕

     編輯:程式設計綜合問答

方案對比

方案優點缺點推薦指數
RecyclerView + ItemTouchHelper (官方)原生支援、效能最好、Material Design 風格、可自定義動畫需理解 Callback 複雜 API⭐⭐⭐⭐⭐
第三方庫 SwipeMenuRecyclerViewAPI 簡單、效果豐富 (左滑菜單、彈性)、文檔完善引入依賴、部分庫停止維護⭐⭐⭐⭐
自定義 ViewGroup + 觸摸事件分發完全可控、無依賴開發成本高、邊界情況易出 bug⭐⭐

方案一:ItemTouchHelper 實現左滑刪除 (核心代碼)


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);

方案二:SwipeMenuRecyclerView 快速集成 (推薦快速開發)


// 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);
    }
});

進階:QQ/微信風格「左滑顯示多個按鈕 (刪除、置頂、標記)」

使用 `SwipeMenuCreator` 添加多個 `SwipeMenuItem` 到 `rightMenu`,或 ItemTouchHelper 中 `onChildDraw` 繪製多個圖標區域並在 `onSwiped` 或自定義觸摸攔截中判斷點擊區域。

避坑指南

  • notifyItemRemoved 後位置偏移:若在 `onSwiped` 中直接操作列表,確保 `vh.getAdapterPosition()` 獲取正確位置 (RV 22.2.0+ 已修復舊版位置 -1 問題)。
  • 項目佈局高度包裹內容:`android:layout_height="wrap_content"` 確保滑動動畫流暢。
  • 長按衝突:ItemTouchHelper 預設長按啟動拖拽,若只需左滑,`SimpleCallback(0, LEFT)` 第一參數傳 0 禁用拖拽。
  • NestedScrolling 衝突:若 RecyclerView 在 ScrollView 內,設置 `rv.setNestedScrollingEnabled(false)`。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved