如何在其中注册一个 DragEvent 并让它在当前的 DragEvent 中侦听? [英] How to register a DragEvent while already inside one and have it listen in the current DragEvent?

查看:37
本文介绍了如何在其中注册一个 DragEvent 并让它在当前的 DragEvent 中侦听?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与 Android 中的拖放 API 有关.如果我的问题令人困惑,我深表歉意.但本质上,当您想要启动拖放操作时,您必须在 View 上调用 startDrag().你将它传递给一些信息,然后你给它一个 OnDragListener 来监听正在被拖动的 View.当开始拖动时,在我的示例中长按,所有可以接受任何信息的视图都向系统注册以接受此信息.如果您快速阅读 拖放.但这只是假设您以前没有使用过并且愿意使用它的情况下对其工作原理的快速概述.

My question is is related to the Drag and Drop API in Android. I apologize if my question was confusing. But essentially, when you want to start a Drag and Drop operation, you must invoke startDrag() on a View. You pass it in some info, and then you give it a OnDragListener in which to listen for a View which is being dragged. When the a drag is started, in my example a long press, all the Views that can accept any info are registered with the system to accept this info. It would make more sense if you quickly read through some of this in the android docs for Drag and Drop. But thats a quick overview of how it works assuming you havent used it before and would like to.

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

Now my question is essentially in an issue I have come across. I would like to create a View while the onDragListener is running that also accepts system info on a currently being dragged View. Problem is its not working. I am not surprised as the View was not registered when when the Drag operation first started. The question is how can I register it on the fly. The android docs shows you how to register it in the beginning but not when its already in one.

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

MyDragListener (Code for my onDragListener. Right now only playing with it.)

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 中,它也不会监听任何拖动,但是当我放下拖动然后长按它时,它起作用了.所以它与它不可见的事实有关,然后它不是.因此,默认情况下,当它不可见时它不会做任何事情,我不知道如何让它不会发生,并允许我让它即使在它不可见时也能做一些事情.有什么想法吗?

So I tried a different approach. I decided to have a holder for my LinearLayout which would be an item in the TableLayout. That way I would register the OnDragListener then I could just hold it until I needed it. That failed. The first time I used it, even if I added it to the TableLayout, it would not Listen to any drags, but when I dropped the drag and then long pressed it, it worked. So it has something to do with the fact that its invisible, and then its not. So by default it does not do anything when its invisible, and I am not sure how to make that not happen, and allow me to have it do something even when its invisible. Any ideas?

推荐答案

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

I know this is an old post but if somebody needs a solution/hack... I had struggled with this for a couple of hours and thought that it might be useful for someone.

我的问题

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

I got this problem when I was trying to have my ListView scroll up/down while I was dragging an item. The issue was that when scrolling, the listview would load new converted views to the group view and the ones that were not active while the drag started (they were in the listview cache - and not associated as children for the view group) did not respond to the dragging.

你的想法是对的,因为视图错过了最初的 DRAG_STARTED 事件,然后它没有收到任何其他事件.

You had the right idea about it, because the view missed the initial DRAG_STARTED event then it wasn't getting any other events.

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

I was going through the source code for VIEW/VIEW GROUP and there are a few ways that we can hack this thing. Eventually I decided to solve it by forcing a visibility change for the problematic view, which will start a chain of events that will eventually include the view in future DRAG EVENTS calls

解决方案:可见性更改技巧

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

So after you have the new view attached to the parent simply set visibility to GONE and back to VISIBLE:

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

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

Note: do this while a) the user is still dragging b) the new view is already added to a parent.

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

Note: For me this was enough to solve the problem. BUT, in my case I had other views in the same container that were already accepting DRAG EVENTS. If this is the first child in that container it might not work. You can try to do the same trick to the container ,and to the container's container, and so on until you reach a container that had children that accept the EVENTS.

这篇关于如何在其中注册一个 DragEvent 并让它在当前的 DragEvent 中侦听?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆