很抱歉,如果我犯了任何愚蠢的错误,但是我找不到它的来源:我正在尝试在我的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的错误。我在其他解决方案中链接的问题跟踪器中添加了一个帖子,但是为了便于阅读,我将在此处对其进行复制。如果您遇到此问题,请转到跟踪器并给该问题加注星标,以期使Android工程师意识到这一点(如意算盘,我知道)。
我在尝试使用拖放APIEditText
在FrameLayout
(非常简单的目标)中移动时遇到了4.4.2中的崩溃/错误。我只有一个OnDragListener
set FrameLayout
,但是很明显,该框架调用了所有子代View
的OnDragEvent()
回调,如在崩溃堆栈跟踪中所示。
发生在内部类的碰撞android.widget.Editor.onDrop()
,其中所述方法试图访问ClipData
从信息DragEvent
传递给该方法。
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
。然后在第1831clipData.getItemCount()
行将触发NPE。似乎仅在发生这种情况,EditText
因为它们具有android.widget.Editor
实例字段,这使我认为这是一个错误/疏忽。
我发现了两个解决方法。
与注释1中建议的解决方法类似,您可以在将接收Drag事件的View层次结构中的对象OnDragListener
上设置虚拟EditText
对象。但是,虚拟侦听器可以只是
myEditText.setOnDragListener( new View.OnDragListener() {
@Override
public boolean onDrag( View v, DragEvent event) {
return true;
}
});
通过仅返回true
所有Drag事件,您将告诉您已经处理了该事件的框架,无论Action的类型是什么(即,通过调用获得的Action event.getAction()
)。这意味着您将拦截Drag事件,并且该事件将不会进一步传递给View的实际OnDragEvent()
回调,因此避免了我们在stacktrace中看到的崩溃。
不需要(event.getAction() == DragEvent.ACTION_DROP)
为该虚拟侦听器提供单独的条件,如注释1所示,因为如果您返回false,ACTION_DRAG_STARTED
则ACTION_DROP
无论如何您将永远不会收到该事件(您可以通过在ACTION_DROP
条件中放置一个日志打印消息来确认这一点,然后会注意到它永远不会被调用,因为您已经返回false
了else
条件)。
由于尝试访问时出现NPEnull
ClipData
中Editor.onDrop()
,你可以简单地提供一个虚拟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);
...
我选择使用helper方法为我ClipData.newPlainText
创建一个简单的纯文本ClipData
,因为您不能仅ClipData
使用其构造函数和null
参数构造a ,因为这也会导致崩溃。
因此,无论在哪里,View.startDrag()
都要确保提供此虚拟道具来开始拖动过程ClipData
。通过这种解决方法,我不需要虚拟对象OnDragListener
,也不会导致NPE崩溃。
注意:如果使用第一种解决方法,请知道通过true
从虚拟对象返回,OnDragListener
可以有效地阻止DragEvent传播到,TextView.onDragEvent()
因此不会调用其中的任何代码。我不确定这样做的副作用,但绝对不是一个空方法。
*编辑:在使用带有EditText
窗口小部件的拖放操作时,我发现确实存在一些奇怪的行为,TextView.onDragEvent()
如果您使用第二种解决方法,最终会被称为。我注意到,当使用ClipData
我建议的虚拟对象时,如果您尝试在周围拖动插入符号同时在文本内移动插入符号,则作为第二个参数传递的“ dummyData ”字符串ClipData.newPlainText()
有时会被粘贴/插入到。EditText
框,或输入EditText
,然后将其拖动。
解释起来很混乱,但是我能够可靠地重现它。如果想尝试并理解它,任何读者都可以看一下该方法的源代码,但老实说,我厌倦了试图找出Android工程师对此的奇怪意图。由于这种奇怪的行为,我更改了第二个解决方法,改为传递一个空String作为第二个参数。这似乎可以缓解问题。
个人而言,我结束了扩展EditText
类,使我自己的,只是覆盖onDragEvent()
到return true;
,而不是调用通过对超类(即TextView.onDragEvent()
,这在本质上是一样的第一个解决方法,但我需要延长EditText
反正类添加一些额外的功能。不管是什么中的原始代码TextView.onDragEvent()
确实如此,跳过它似乎并不影响我的个人用例,并且我也没有注意到我需要的任何功能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句