0

我的问题与 Android 中的拖放 API 有关。如果我的问题令人困惑,我深表歉意。但本质上,当您想要启动拖放操作时,您必须调用startDrag(). View你把它传递给一些信息,然后你给它一个OnDragListener监听View被拖拽的对象。当开始拖动时,在我的示例中长按,所有可以接受任何信息的视图都向系统注册以接受此信息。如果您快速阅读有关Drag and Drop的 android 文档中的一些内容,这将更有意义。但是,假设您以前没有使用过它并且想要使用它,那么这就是它如何工作的快速概述。

现在我的问题本质上是我遇到的一个问题。我想创建一个View正在onDragListener运行的时间,它还接受当前正在拖动的系统信息View。问题是它不工作。我并不感到惊讶,因为当拖动操作第一次开始时视图没有注册。问题是我如何即时注册它。android 文档向您展示了如何在开始时注册它,而不是在它已经在一个时注册。

MyDragListener(我的 onDragListener 的代码。现在只玩它。)


protected class MyDragListener implements View.OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {

        // Defines a variable to store the action type for the incoming event
        final int action = event.getAction();

        // Handles each of the expected events
            switch(action) {

                case DragEvent.ACTION_DRAG_STARTED:
                    // Determines if this View can accept the dragged data
                    /*The way it works is it essentially turns anything that can accept stuff to Blue 
                     * or whatever color. It also does not need to do anything in terms of showing it can accept anything.*/
                    if(event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                        v.setBackgroundColor(Color.BLUE);

                        return (true);

                    } else {
                        return (false);
                    }
                //break;

                case DragEvent.ACTION_DRAG_ENTERED:
                    v.setBackgroundColor(Color.YELLOW);
                    Toast.makeText(v.getContext(), "Height is: "+v.getHeight(), Toast.LENGTH_SHORT).show();
                    return true;
                //break;

                case DragEvent.ACTION_DRAG_LOCATION:
                    //this is triggered right after ACTIN_DRAG_ENTERED
                    Log.d("TestActivity", "Location of the View you are dragging is x: "+event.getX()+" y: "+event.getY());
                    if(v.getHeight()-10 < event.getY() && v.getHeight() > event.getY()&& showingView == false ) {

                            //here you are checking if its in the lower bound of the view
                            LayoutInflater inflater = LayoutInflater.from(v.getContext());
                            LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.some_text, table, false);
                            ((TextView)layout.findViewById(R.id.da_text)).setText("Some text");
                            layout.setTag("Empty");
                            layout.startDrag(ClipData.newPlainText("Empty", "Empty"), new View.DragShadowBuilder(), null, 0);
                            table.addView(layout, Integer.parseInt(v.getTag().toString())+1);
                        showingView = true;
                    }
                    return true;


                case DragEvent.ACTION_DRAG_EXITED:
                    v.setBackgroundColor(Color.BLUE);
                    return true;
                //break;

                case DragEvent.ACTION_DROP:
                    //this is obvious, gets the data in the view that was dropped
                    return true;

                case DragEvent.ACTION_DRAG_ENDED:
                    v.setBackgroundColor(Color.WHITE);
                    return true;


            }//end of switch

        return false;
    }

}//end of MyDragListener

编辑 1

所以我尝试了不同的方法。我决定为我准备一个支架,LinearLayout这将是TableLayout. 这样我就可以注册OnDragListener然后我可以拿着它直到我需要它。那失败了。我第一次使用它,即使我将它添加到 TableLayout 中,它也不会监听任何拖动,但是当我放下拖动然后长按它时,它起作用了。所以它与它不可见的事实有关,然后它不是。因此,默认情况下,当它不可见时它不会做任何事情,我不知道如何让它不会发生,并允许我让它即使在它不可见时也能做一些事情。有任何想法吗?

4

2 回答 2

4

我知道这是一篇旧帖子,但如果有人需要解决方案/破解......我已经为此苦苦挣扎了几个小时,并认为它可能对某人有用。

我的问题

当我试图让我的 ListView 在拖动项目时向上/向下滚动时遇到了这个问题。问题是滚动时,列表视图会将新的转换视图加载到组视图中,而在拖动开始时未激活的视图(它们在列表视图缓存中 - 并且未关联为视图组的子视图)没有响应到拖。

您对此有正确的想法,因为视图错过了最初的 DRAG_STARTED 事件,然后它没有收到任何其他事件。

我正在浏览 VIEW/VIEW GROUP 的源代码,有几种方法可以破解这个东西。最终我决定通过强制更改有问题的视图的可见性来解决它,这将启动一系列事件,最终将在未来的 DRAG EVENTS 调用中包含该视图

解决方案:可见性更改黑客

因此,在将新视图附加到父视图后,只需将可见性设置为 GONE 并返回 VISIBLE:

child.setVisibility(View.GONE);
child.setVisibility(View.VISIBLE);

注意:在 a) 用户仍在拖动 b) 新视图已添加到父视图时执行此操作。

注意:对我来说,这足以解决问题。但是,在我的情况下,我在同一个容器中有其他视图已经接受了 DRAG 事件。如果这是该容器中的第一个孩子,它可能不起作用。您可以尝试对容器和容器的容器执行相同的技巧,依此类推,直到您到达具有接受 EVENTS 的子级的容器。

于 2013-02-26T19:25:48.623 回答
0

老问题,但我试图做一些非常相似的事情。一种对我有用的更清洁的方法是:

  1. 将 DragListener 附加到 ExpandableListView 而不是其中的各个视图。

  2. 然后根据 DragEvent.ACTION_DRAG_LOCATION 事件的 x,y 坐标,识别组或子视图并执行所需的操作。

这样,在拖动事件开始时,组/子视图不必可见。

于 2016-08-29T20:43:44.230 回答