drag and drop 实现课程表拖拽功能

简介

        本文会基于html5 的drag and drop 实现课程表拖拽功能。

实现效果

技术实现

源码

function App() {

    const m = 3;
    const n = 3;
    const courses = ['语文', '数学', '英文']

    return <div style={{display: 'flex'}}>
        <div style={{
            display: 'grid',
            gridTemplateColumns: `repeat(${n}, 1fr)`,
            gridTemplateRows: `repeat(${m}, 1fr)`,
            gridGap: '10px',
            margin: '5vw 5vw',
            backgroundColor: '#f1f1f1'
        }}>
            {
                Array.from({length: m}, (row, i) => {
                    return Array.from({length: n}, (col, j) => {
                        return <div
                                    onDragOver={(e) => e.preventDefault()}
                                    onDrop={(e) => {
                                        e.preventDefault();
                                        var itemId = e.dataTransfer.getData('item-id');
                                        const nItem = document.getElementById(itemId).cloneNode(true);
                                        e.currentTarget.replaceChild(nItem, e.currentTarget.childNodes[0]);
                                    }}
                        >
                            <div key={i + '-' + j}
                                style={{ padding: '20px',backgroundColor: 'lightblue', border: '1px solid #ccc'}}
                            > {
                                courses[Math.floor(Math.random() * courses.length)]

                            }</div>
                        </div>
                    })
                })
            }

        </div>
        <div style={{margin: '5vw 5vw'}}>
            <div id="course-wuli"
                 style={{padding: '20px', width: 'fit-content', backgroundColor: 'lightblue', border: '1px solid #ccc'}}
                 draggable={true}
                 onDragStart={(e) => {
                     e.dataTransfer.setData('item-id', 'course-wuli');
                 }}
            >物理
            </div>

            <div id="course-computer"
                 style={{padding: '20px', width: 'fit-content', backgroundColor: 'lightblue', border: '1px solid #ccc'}}
                 draggable={true}
                 onDragStart={(e) => {
                     e.dataTransfer.setData('item-id', 'course-computer');
                 }}
            >电脑
            </div>
        </div>
    </div>
}

html5 drag and drop

HTML5 拖放 | 菜鸟教程

        drag and drop api 可以参考上面菜鸟文档。

实现这个功能,你需要实现以下几个步骤: 1. 在 Recycleview 的 item layout 中添加一个可接受拖放的 View。 2. 在外部 View 上注册一个拖放监听器。 3. 在拖放监听器中实现 onDrag() 方法,用于创建一个拖放阴影,并将其与拖放事件绑定。 4. 在 onDrag() 方法中,你需要将拖放事件传递给 Recycleview 的 ItemTouchHelper 对象。 5. 在 ItemTouchHelper.Callback 的实现中,你需要实现 onMove() 方法,将外部 View 拖放到 Recycleview 中的指定位置,并更新数据集合。 6. 最后,你需要调用 notifyItemInserted() 方法来刷新 Recycleview 的显示。 下面是一个大致的实现方案: ``` class MyAdapter extends RecyclerView.Adapter<MyViewHolder> implements ItemTouchHelper.Callback { List<Item> mData; // ... @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 创建 ViewHolder 对象,并将其绑定到一个 item layout 上。 View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); // 在 item layout 中添加一个可接受拖放的 View。 View dropView = itemView.findViewById(R.id.drop_view); // 注册拖放监听器。 dropView.setOnDragListener(new MyDragListener()); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { // 将数据绑定到 ViewHolder 上。 } // ... @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { // 将外部 View 拖放到 Recycleview 中的指定位置,并更新数据集合。 int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); Collections.swap(mData, fromPosition, toPosition); // 刷新 Recycleview 的显示。 notifyItemMoved(fromPosition, toPosition); return true; } // ... } class MyDragListener implements View.OnDragListener { @Override public boolean onDrag(View v, DragEvent event) { // 创建一个拖放阴影,并将其与拖放事件绑定。 View shadowView = v; ClipData clipData = ClipData.newPlainText("", ""); View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(shadowView); v.startDrag(clipData, shadowBuilder, v, 0); // 将拖放事件传递给 ItemTouchHelper 对象。 ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new MyAdapter()); itemTouchHelper.startDrag(event); return true; } } ``` 需要注意的是,以上代码仅供参考,具体实现方式可能会因为业务需求而有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值