首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在`ListView`中拖放

在`ListView`中拖放
EN

Stack Overflow用户
提问于 2012-12-06 14:49:39
回答 4查看 3.1K关注 0票数 18

我正试着在安卓(冰淇淋三明治)的ListView中实现拖放。因此,当被拖动的对象到达ListView的边缘时,我将在相关方向上滚动ListView。问题是,当我们滚动时,有时适配器会根据需要创建新的View,并且这些“新的”View没有早先接收到ACTION_DRAG_STARTED事件,因此没有接收到DragEvent更新。有没有办法我也可以把事件发送到这些视图?

EN

回答 4

Stack Overflow用户

发布于 2012-12-14 16:57:09

在listview中实现拖放的最简单方法是使用这个很棒的库。https://github.com/commonsguy/cwac-touchlist,值得一试。

票数 1
EN

Stack Overflow用户

发布于 2012-12-11 16:43:24

查看View的源代码,我看到:

代码语言:javascript
复制
static final int DRAG_CAN_ACCEPT              = 0x00000001;
int mPrivateFlags2;

boolean canAcceptDrag() {
    return (mPrivateFlags2 & DRAG_CAN_ACCEPT) != 0;
}

mPrivateFlags2是包私有的,不会被SDK公开。但是,您应该能够通过执行以下操作在子类中更改它:

代码语言:javascript
复制
try {
    Field mPrivateFlags2 = this.getClass().getField("mPrivateFlags2");
    int currentValue = mPrivateFlags2.getInt(this);
    mPrivateFlags2.setInt(this, currentValue | 0x00000001);
} catch (Exception e) {
}
票数 0
EN

Stack Overflow用户

发布于 2013-01-03 02:09:58

我有same problem。我没有解决这个回收问题,但我发现了一个可能的变通方法,仍然使用拖放框架。这个想法是为了改变视角:不是在列表中的每个View上使用OnDragListener,而是可以直接在ListView上使用它。

然后,在执行拖放操作时,找到手指位于哪个项目的顶部,并在ListViewListAdapter中编写相关的显示代码。然后,技巧是找到我们在哪个项目视图的顶部,以及在哪里完成了拖放。

为此,我将适配器创建的每个视图的ListView位置设置为id -使用View.setId(),这样我以后就可以使用ListView.pointToPosition()ListView.findViewById()的组合找到它。

作为一个拖拽监听器的例子(我提醒你,这是在ListView上应用的),它可以是这样的:

代码语言:javascript
复制
// Initalize your ListView
private ListView _myListView = new ListView(getContext());

// Start drag when long click on a ListView item
_myListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
        view.startDrag(null, shadowBuilder, _myListView.getItemAtPosition(position), 0);
        return true;
    }
});

// Set the adapter and drag listener
_myListView.setOnDragListener(new MyListViewDragListener());
_myListView.setAdapter(new MyViewAdapter(getActivity()));

// Classes used above

private class MyViewAdapter extends ArrayAdapter<Object> {
    public MyViewAdapter (Context context, List<TimedElement> objects) {
        super(context, 0, objects);
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View myView = convertView;
        if (myView == null) {
            // Instanciate your view
        }
        // Associates view and position in ListAdapter, needed for drag and drop
        myView.setId(position);
        return myView;
    }
}


private class MyListViewDragListener implements View.OnDragListener {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        final int action = event.getAction();
        switch(action) {
            case DragEvent.ACTION_DRAG_STARTED:
                return true;
            case DragEvent.ACTION_DRAG_DROP:
                // We drag the item on top of the one which is at itemPosition
                int itemPosition = _myListView.pointToPosition((int)event.getX(), (int)event.getY());
                // We can even get the view at itemPosition thanks to get/setid
                View itemView = _myListView.findViewById(itemPosition );
                /* If you try the same thing in ACTION_DRAG_LOCATION, itemView
                 * is sometimes null; if you need this view, just return if null.
                 * As the same event is then fired later, only process the event
                 * when itemView is not null.
                 * It can be more problematic in ACTION_DRAG_DROP but for now
                 * I never had itemView null in this event. */
                // Handle the drop as you like
                return true;
         }
    }
}

现在,如果您需要在进行拖放操作时获得视觉反馈,有几种策略可供选择。例如,在您的活动中可以有两个实例变量,名为:

代码语言:javascript
复制
private boolean ongoingDrag = false; // To know if we are in a drag&drop state
private int dragPosition = 0; // You put the itemPosition variable here

MyListViewDragListener中进行拖放操作时,您可以修改这些变量,并在MyViewAdapter中使用它们的状态。当然,不要忘记使用诸如_myListView.getAdapter()).notifyDataSetChanged()_myListView.invalidate()方法之类的东西来更新UI (当然,在事件线程中使用处理程序)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13738371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档