gpt4 book ai didi

android - 如何在 Android 中拖放 EditText 的内容?

转载 作者:行者123 更新时间:2023-11-29 01:29:13 25 4
gpt4 key购买 nike

简而言之,我想让用户能够拖放 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 被点击时,它被一个 Fragment 替换,该 Fragment 的 XML 包含一个 LinearLayout 持有 2 个 EditTexts。我在 onCreate() 中为这些 EditText 设置了触摸和拖动监听器,并将这些类添加到上述 fragment 中:

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;
}

}

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

感谢任何建议,谢谢。

编辑:

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

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 中删除了拖动监听器(保留了触摸监听器)并将其添加到我想将它们放入的 View 中。我不再收到错误的丢弃消息,我确定它正在丢弃 EditText,因为当它们被拖出时 fragment 会变小。我仍然看不到他们。会不会是它们被丢弃在 View 后面而不是 View 前面?如果是这样,我该如何避免呢?再次感谢。

编辑:凹凸

最佳答案

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

ViewGroup 类中粗略地浏览一下这个调用似乎表明在 ViewGroup 的 subview 中搜索可以接受 放置 - 如果没有 subview 从 dispatchDragEvent() 返回 true,放置将中止。

在您的问题中,您声明:我已经为这些 EditText 的...设置了触摸和拖动监听器,但是您是否为布局设置了任何拖动监听器EditText 的 被删除了吗?

我的猜测(这是一个猜测!)是正在向放置 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 时。

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

无论如何,在添加 EditText 之前调用 setFocusable() 可以让它在我的设备上运行。 this question的答案也是这样做的。

关于android - 如何在 Android 中拖放 EditText 的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32230698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com