gpt4 book ai didi

android - 在Nexus上onDragEvent()抛出nullpointer

转载 作者:行者123 更新时间:2023-11-29 15:17:45 26 4
gpt4 key购买 nike

很抱歉,如果我犯了任何愚蠢的错误,但是我找不到此信息的来源:
我正在尝试在我的EditText“ etItem”上实现onDrag侦听器
这是我的代码:

 etItem.setOnDragListener(new OnDragListener(){

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

if(null!=dragevent && null!=v){

if( dragevent.getAction() == DragEvent.ACTION_DROP )
{
View view = (View) dragevent.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();

int itemNum = (Integer) view.getTag();
itemAmounts[itemNum] = 0;
owner.removeView(view);
return true;

}
}
return false;
}});


这在我的Samsng Galaxy Grand上运行正常,但是在Nexus上给了我一个空指针。

stackTrace:

03-26 15:47:21.185: E/AndroidRuntime(1439): FATAL EXCEPTION: main
03-26 15:47:21.185: E/AndroidRuntime(1439): java.lang.NullPointerException
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.widget.Editor.onDrop(Editor.java:1797)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.widget.TextView.onDragEvent(TextView.java:8350)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.View.dispatchDragEvent(View.java:16375)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1237)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:3838)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewRootImpl.access$600(ViewRootImpl.java:95)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2999)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.os.Handler.dispatchMessage(Handler.java:99)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.os.Looper.loop(Looper.java:137)
03-26 15:47:21.185: E/AndroidRuntime(1439): at android.app.ActivityThread.main(ActivityThread.java:5041)
03-26 15:47:21.185: E/AndroidRuntime(1439): at java.lang.reflect.Method.invokeNative(Native Method)
03-26 15:47:21.185: E/AndroidRuntime(1439): at java.lang.reflect.Method.invoke(Method.java:511)
03-26 15:47:21.185: E/AndroidRuntime(1439): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-26 15:47:21.185: E/AndroidRuntime(1439): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-26 15:47:21.185: E/AndroidRuntime(1439): at dalvik.system.NativeStart.main(Native Method)
03-26 15:47:21.345: W/ActivityManager(297): Force finishing activity com.listcalc.main/.MainActivityFree

最佳答案

我认为这是EditText小部件和Android中的拖放API的错误。我在其他解决方案中链接的问题跟踪器中添加了一个帖子,但是为了便于阅读,我将在此处进行复制。如果您遇到此问题,请please go to the tracker并加注星标,以期使Android工程师意识到这一点(我想是如意算盘)。

撞车原因

我在尝试使用拖放API在EditText中移动FrameLayout(非常简单的目标)时遇到了4.4.2中的崩溃/错误。我在我的OnDragListener上仅设置了一个FrameLayout,但是很显然,该框架调用了所有子级ViewOnDragEvent()回调,如在崩溃堆栈跟踪中所示。

崩溃发生在内部类android.widget.Editor.onDrop()中,在该类中该方法尝试从传递给该方法的ClipData中访问DragEvent信息。

From 4.4.2 source

1828    void onDrop(DragEvent event) {
1829 StringBuilder content = new StringBuilder("");
1830 ClipData clipData = event.getClipData();
1831 final int itemCount = clipData.getItemCount();
1832 for (int i=0; i < itemCount; i++) {
1833 Item item = clipData.getItemAt(i);
1834 content.append(item.coerceToStyledText(mTextView.getContext()));
1835 }
....


在行1830中, event.getClipData()返回 null。然后在第1831行中, clipData.getItemCount()将触发NPE。这似乎只发生在 EditText上,因为它们有一个 android.widget.Editor实例字段,这使我认为这是一个错误/疏忽。

我发现了两个解决方法。

第一种解决方法:

与注释1中建议的解决方法类似,您可以在将接收拖动事件的View层次结构中的 OnDragListener对象上设置虚拟 EditText。但是,虚拟侦听器可以只是

myEditText.setOnDragListener( new View.OnDragListener() {
@Override
public boolean onDrag( View v, DragEvent event) {
return true;
}
});


通过仅返回所有Drag事件的 true,您将告诉您已经处理了该事件的框架,无论Action的类型是什么(即,通过调用 event.getAction()获得的操作)。这意味着您将拦截Drag事件,并且不会将其进一步传递给View的实际 OnDragEvent()回调,因此避免了我们在stacktrace中看到的崩溃。

不必为该虚拟侦听器的注释#1看到单独的 (event.getAction() == DragEvent.ACTION_DROP)条件,因为如果您为 ACTION_DRAG_STARTED返回false,则无论如何都不会收到 ACTION_DROP事件(您可以通过放置 ACTION_DROP条件下的日志打印消息,您会发现它从未被调用,因为您已经在 false条件下返回了 else

第二种解决方法:*编辑(请参见下文)

由于在尝试访问 null中的 ClipData Editor.onDrop()时会发生NPE,因此在开始拖动过程​​时,只需向 ClipData提供一个虚拟 DragEvent

这是我针对自己的情况做的事情:

... <other code>
ClipData dummyData = ClipData.newPlainText("dummyData", ""); // don't forget to pass empty String
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(dummyData, shadowBuilder, v, 0);
...


我选择使用辅助方法 ClipData.newPlainText为我创建一个简单的纯文本 ClipData,因为您不能仅使用其构造函数和 ClipData参数构造一个 null,因为这也会导致崩溃。

因此,无论在哪里使用 View.startDrag()开始拖动过程​​,请确保提供此虚拟 ClipData。通过这种解决方法,我不需要虚拟 OnDragListener,也不会出现NPE崩溃。

注意:如果使用第一种解决方法,请知道通过从虚拟 true返回 OnDragListener,您将有效地阻止DragEvent传播到 TextView.onDragEvent(),因此不会调用其中的任何代码。我不确定这样做的副作用,但是绝对不是一个空方法。

*编辑:在使用 EditText小部件进行拖放操作时,我发现 TextView.onDragEvent()确实存在一些奇怪的行为,如果您采用第二种解决方法,最终会被称为。我注意到,当使用我建议的虚拟 ClipData时,如果您尝试将窗口小部件拖动到 ClipData.newPlainText()的第二个参数中,则传递给您的“ dummyData”字符串有时会粘贴/插入到 EditText中。同时在文本框中移动插入符号,或通过键入 EditText然后将其拖动到位。

解释起来很混乱,但是我能够可靠地重现它。如果想尝试并理解它,任何读者都可以 take a look at the source code尝试使用该方法,但是老实说,我厌倦了试图找出Android工程师对此的奇怪意图。由于这种奇怪的行为,我更改了第二个解决方法,改为传递一个空String作为第二个参数。这似乎减轻了问题。

就我个人而言,我最终扩展了 EditText类,并创建了自己的类,并简单地将 onDragEvent()覆盖为 return true;,而不调用超类(即 TextView.onDragEvent()。这本质上与第一种解决方法相同,但我需要无论如何扩展 EditText类以添加一些额外的功能,无论 TextView.onDragEvent()中的原始代码做什么,跳过它似乎都不会影响我的个人用例,并且我也没有发现我需要的任何功能。

关于android - 在Nexus上onDragEvent()抛出nullpointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22667098/

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