【问题标题】:How to drag and drop content of EditText in Android?如何在 Android 中拖放 EditText 的内容?
【发布时间】:2015-08-26 15:26:37
【问题描述】:

简而言之,我想让用户能够拖放EditText - 但是,当EditText 被释放而不是放下时,由于某种原因它消失了,我收到消息:

I/ViewRootImpl﹕ Reporting drop result: false

我有一个带有 2 个 FrameLayout、camera_preview 和 bottom_toolbar 的 Activity,如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_above="@+id/bottom_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/bottom_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true">

    </FrameLayout>
</RelativeLayout>

当bottom_toolbar被点击时,它被一个片段替换,该片段的XML包含一个包含2个EditTexts的LinearLayout。我在 onCreate() 中为这些 EditText 设置了触摸和拖动侦听器,并将这些类添加到所述片段中:

private final class MyTouchListener implements View.OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            view.setVisibility(View.INVISIBLE);
            view.startDrag(data, shadowBuilder, view, 0);
            return true;
        }
        else
        {
            return false;
        }
    }
}

class MyDragListener implements View.OnDragListener {
    private android.widget.LinearLayout.LayoutParams layoutParams;

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                layoutParams = (LinearLayout.LayoutParams) v.getLayoutParams();
                Log.d("TAG", "Started");
            break;
            case DragEvent.ACTION_DRAG_ENTERED:
                int x_cord = (int) event.getX();
                int y_cord = (int) event.getY();
                Log.d("TAG", "Entered");
                break;
            case DragEvent.ACTION_DRAG_EXITED:
                x_cord = (int) event.getX();
                y_cord = (int) event.getY();
                layoutParams.leftMargin = x_cord;
                layoutParams.topMargin = y_cord;
                v.setLayoutParams(layoutParams);
                Log.d("TAG", "Exited");
                break;

            case DragEvent.ACTION_DRAG_LOCATION:
                x_cord = (int) event.getX();
                y_cord = (int) event.getY();
                Log.d("TAG", "Loc");
                break;

            case DragEvent.ACTION_DRAG_ENDED:
                //((View)event.getLocalState()).setVisibility(View.VISIBLE);
                v.setVisibility(View.VISIBLE);
                Log.d("TAG", "Ended");
                break;

            case DragEvent.ACTION_DROP:
                v.setVisibility(View.VISIBLE);
                Log.d("TAG", "Dropped");
                break;
            default:

            break;
        }
        return true;
    }

}  

有人知道为什么我的EditTexts 在我放下它们时会消失吗?我在网上花了无数个小时寻找解决方案,但似乎都没有奏效。

感谢任何建议,谢谢。

编辑:

将我的拖动监听器更改为:

class MyDragListener implements View.OnDragListener {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                    break;
                case DragEvent.ACTION_DROP:
                    View view = (View) event.getLocalState();
                    ViewGroup owner = (ViewGroup) view.getParent();
                    owner.removeView(view);
                    FrameLayout container = (FrameLayout) v;
                    container.addView(view);
                    view.setVisibility(View.VISIBLE);
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                default:
                    break;
            }
            return true;
        }
    }

我从EditText 中删除了拖动监听器(保留了触摸监听器)并将其添加到我想要将它们放入的视图中。我不再收到错误的丢弃消息,并且我确定它正在丢弃EditText,因为当它们被拖出片段时,片段会变小。不过我还是看不到他们。会不会是他们被丢在视野后面而不是前面?如果是这样,我该如何避免呢?再次感谢。

编辑:凹凸

【问题讨论】:

  • “我在 onCreate() 中为这些 EditText 设置了触摸和拖动监听器”。你的意思是你已经在 EditText 本身或包含 EditText 的布局上设置了侦听器?
  • 在 EditText 本身上。

标签: android android-layout android-fragments drag-and-drop


【解决方案1】:

查看 Android 源代码,Reporting drop result: falsedispatchDragEvent() 调用的直接结果。

粗略扫描ViewGroup 类中的此调用似乎表明ViewGroup 的子视图被搜索以寻找可以接受 放置的子视图 - 如果没有子视图返回@ 987654326@ from dispatchDragEvent(),drop 被中止。

在您的问题中,您声明:I have set touch and drag listeners for these EditText's...,但是您是否为放置EditText's布局 设置了任何拖动侦听器?

我的猜测(这是一个猜测!)是正在为放置 EditText 的布局本身正在查询放置处理程序,但不存在。换句话说,您需要在被拖放到的布局上设置一个拖动侦听器 - 并从中返回 true。

编辑

我使用与您发布的代码相同的代码创建了一个应用,我看到的结果与您相同 - EditText 已移动,但不再可见。

我认为这里发生了几件事。首先,在将EditText 放到它上面之前,您似乎需要使接收FrameLayout 成为焦点:

case DragEvent.ACTION_DROP:
  View view = (View) event.getLocalState();
  ViewGroup owner = (ViewGroup) view.getParent();
  owner.removeView(view);
  FrameLayout container = (FrameLayout) v;
  // make it focusable first
  container.setFocusable(true);
  // now add the view
  container.addView(view);
  view.setVisibility(View.VISIBLE);
  break;

其次,您将完整的 EditText 作为 localstate 对象传递 - 我认为您不应该这样做。从文档来看,localstate 似乎应该很简单——我建议将其设为被拖动的EditTextid,并在拖放时使用findViewById() 以获得正确的视图。

为了将来参考,选择更好的变量名并尝试注释您的代码。当您将变量命名为 view 时,真的很难弄清楚发生了什么!

无论如何,在添加EditText 之前调用setFocusable() 可以使其在我的设备上运行。回复this question 也可以。

【讨论】:

  • 您好,谢谢您,我听从了您的建议并取得了一些进展。 EditText 现在肯定被丢弃了,我只是看不到它们(怀疑它们被丢弃在目标视图后面)。你能看看我的编辑吗?
  • @eyesenberg 添加回复
  • 由于某种原因仍然无法正常工作。当我将 FrameLayout 更改为 LinearLayout 时,它会显示元素但在左上角而不是在释放拖动的位置。使用 RelativeLayout 其结果与 FrameLayout 相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 1970-01-01
相关资源
最近更新 更多