Recyclerview进阶——元素拖拽及侧滑删除

之前一直觉得列表的拖拽换位和侧滑删除是很难实现的,不过之后参考了下几篇博客后发,发现还是很简单的,因为suppor早就封装好了,最主要的是继承ItemTouchHelper.Callback,并对其方法

 

效果图如下:

步骤如下:

1、新建类并继承ItemTouchHelper.Callback,在其对应方法设置相应操作包括,不同布局的拖拽和侧滑删除,选择效果

2、Adapter中实现自定义的监听回调,对位置交换和删除动作做对应的数据操作和界面的刷新

3、主代码中 新建ItemTouchHelper 并关联RecyclerView即可

代码如下:

1、新建类并继承ItemTouchHelper.Callback,在其对应方法设置相应操作

public interface ItemTouchHelperAdapter {
    //数据交换
    void onItemMove(int fromPosition,int toPosition);
    //数据删除
    void onSwiped(int position);
}
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {

    private ItemTouchHelperAdapter mAdapter;
    private boolean dragEnabled;        //能否拖拽
    private boolean swipeEnabled;       //能否侧滑


    public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter, boolean dragEnabled, boolean swipeEnabled) {
        mAdapter = adapter;
        this.dragEnabled = dragEnabled;
        this.swipeEnabled = swipeEnabled;
    }

    //同来设置 拖拽移动,或移动删除
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {// GridLayoutManager
            // flag如果值是0,相当于这个功能被关闭
            int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            int swipeFlag = 0;
            // create make
            return makeMovementFlags(dragFlag, swipeFlag);
        } else if (layoutManager instanceof LinearLayoutManager) {// linearLayoutManager
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
            int orientation = linearLayoutManager.getOrientation();

            int dragFlag = 0;
            int swipeFlag = 0;

            // 为了方便理解,相当于分为横着的ListView和竖着的ListView
            if (orientation == LinearLayoutManager.HORIZONTAL) {// 如果是横向的布局
                swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            } else if (orientation == LinearLayoutManager.VERTICAL) {// 如果是竖向的布局,相当于ListView
                dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            }
            return makeMovementFlags(dragFlag, swipeFlag);
        }
        return 0;
    }

    //是否能拖动
    @Override
    public boolean isLongPressDragEnabled() {
        return dragEnabled;
    }

    //是否能侧滑
    @Override
    public boolean isItemViewSwipeEnabled() {
        return swipeEnabled;
    }

    //拖动
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        Log.e(TAG, "onMove");
//        if (viewHolder.getAdapterPosition() == 0) {
            //第一个无法拖拽
//            return false;
//        }
        mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    //左右滑动
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mAdapter.onSwiped(viewHolder.getAdapterPosition());
        Log.e(TAG, "onSwiped");
    }

    //选中项操作
    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        Log.e(TAG, "onSelectedChanged");

        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            if (viewHolder != null)
                viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
        }
    }

    //释放选中项操作
    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        Log.e(TAG, "clearView");
        viewHolder.itemView.setBackgroundColor(0);
    }
}

2、Adapter中实现自定义的监听回调

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Holder> implements ItemTouchHelperAdapter {

    private Context mContext;
    private List<String> mList;

    public MyAdapter(Context context, List<String> list) {
        mContext = context;
        mList = list;
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new Holder(LayoutInflater.from(mContext).inflate(R.layout.item_test, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final Holder holder, final int i) {
        holder.tvF.setText(mList.get(i));
        holder.tvS.setText(mList.get(i));
        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //移除数据
                mList.remove(i);
                notifyDataSetChanged();
            }
        });
    }

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

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        //交换位置
        Collections.swap(mList, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
    }

    @Override
    public void onSwiped(int position) {
        //移除数据
        mList.remove(position);
        notifyItemRemoved(position);
    }

    static class Holder extends RecyclerView.ViewHolder {
        private TextView tvF;
        private TextView tvS;
        private ImageView delete;

        public Holder(@NonNull View itemView) {
            super(itemView);
            tvF = itemView.findViewById(R.id.tv_first);
            tvS = itemView.findViewById(R.id.tv_second);
            delete = itemView.findViewById(R.id.delete);
        }
    }
}

3、主代码中 新建ItemTouchHelper 并关联RecyclerView

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "recyclerviewmove";
    private Button btnChange;
    private RecyclerView mRecyclerView;
    private MyAdapter mMyAdapter;

    private List<String> mList = new ArrayList<>();
    private boolean bGrid;      //布局标识


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        for (int i = 0; i < 9; i++) {
            mList.add(i + "" + i + "" + i);
        }
        mRecyclerView = findViewById(R.id.recycler_view);
        btnChange = findViewById(R.id.btn_change);

        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mMyAdapter = new MyAdapter(this, mList);
        mRecyclerView.setAdapter(mMyAdapter);
        //关联ItemTouchHelper和RecyclerView
        ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(mMyAdapter,true,true);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(mRecyclerView);

        btnChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bGrid) {
                    mRecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
                } else {
                    mRecyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this, 4));
                }
                bGrid = !bGrid;
            }
        });
    }
}

参考:RecyclerView进阶:使用ItemTouchHelper实现拖拽和侧滑删除_recyclerview把item可以拖拽到任意地方具体实现_程序员的自我反思的博客-CSDN博客

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!关于您的问题,可以通过以下步骤实现: 1.创建一个 QTableWidget,设置行和列的数量。 ```cpp QTableWidget* tableWidget = new QTableWidget(rowCount, columnCount, this); ``` 2.在单元格中添加文本。 ```cpp tableWidget->setItem(row, column, new QTableWidgetItem("text")); ``` 3.设置 QTableWidget 的拖放模式为 MoveAction,以便可以将单元格拖动到另一个单元格中。 ```cpp tableWidget->setDragDropMode(QAbstractItemView::DragDropMode::MoveAction); ``` 4.实现 QTableWidget 的拖动事件,获取拖动单元格的行和列。 ```cpp void MyTableWidget::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { QTableWidgetItem* item = itemAt(event->pos()); if (item != nullptr) { m_draggedItem = item; m_draggedRow = item->row(); m_draggedColumn = item->column(); } } } void MyTableWidget::mouseMoveEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton && m_draggedItem != nullptr) { QMimeData* mimeData = new QMimeData; QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); dataStream << m_draggedRow << m_draggedColumn; mimeData->setData("application/x-qabstractitemmodeldatalist", itemData); QDrag* drag = new QDrag(this); drag->setMimeData(mimeData); drag->exec(Qt::MoveAction); } } void MyTableWidget::dragEnterEvent(QDragEnterEvent* event) { event->acceptProposedAction(); } void MyTableWidget::dragMoveEvent(QDragMoveEvent* event) { event->acceptProposedAction(); } void MyTableWidget::dragLeaveEvent(QDragLeaveEvent* event) { event->accept(); } ``` 5.实现 QTableWidget 的放置事件,将拖动单元格的文本替换为目标单元格的文本。 ```cpp void MyTableWidget::dropEvent(QDropEvent* event) { QPoint dropPoint = event->pos(); int row = rowAt(dropPoint.y()); int column = columnAt(dropPoint.x()); QTableWidgetItem* targetItem = item(row, column); if (targetItem != nullptr) { QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist"); QDataStream dataStream(&itemData, QIODevice::ReadOnly); int draggedRow, draggedColumn; dataStream >> draggedRow >> draggedColumn; QTableWidgetItem* draggedItem = item(draggedRow, draggedColumn); if (draggedItem != nullptr) { QString text = draggedItem->text(); draggedItem->setText(targetItem->text()); targetItem->setText(text); } } event->acceptProposedAction(); } ``` 这样,就可以实现 QTableWidget 的拖拽单元格并替换内容了。希望可以帮到您!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值