我有一个 GridView。GridView 中的每个项目都是水平(或垂直)布局(取决于方向)。该布局内部是一个 ImageView 和一个 TextView。
当我在除 GridView 中的第一个以外的任何 ImageView 上执行“长按”时,一切都按计划进行。在 onLongPress() 处理程序中,我在 ImageView 上调用 startDrag,一切都按计划进行。如果我在 GridView 中的第一个 ImageView 上执行“长按”,我会在 Android View 的 startDrag() 方法中得到 NullPointer 异常。
08-16 10:11:04.425: E/View(2456): Unable to initiate drag
08-16 10:11:04.425: E/View(2456): java.lang.NullPointerException
08-16 10:11:04.425: E/View(2456): at android.view.View.startDrag(View.java:16281)
08-16 10:11:04.425: E/View(2456): at org.xyzzy.test.GridLauncher$ShortCutTouchListener$ShortcutGestureListener.onLongPress(RemoteLauncher.java:650)
08-16 10:11:04.425: E/View(2456): at android.view.GestureDetector.dispatchLongPress(GestureDetector.java:675)
我能够验证传递给 startDrag 的所有参数都是非空的 - ClipData、DragShadowBuilder 和我的 ImageView 作为 LocalState。这是该代码片段:
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(mView);
boolean doingDrag = mView.startDrag(data, shadowBuilder, mView, 0);
startDrag 返回 false 并且 logcat 包含 Unable to start drag 消息和异常跟踪。
这只发生在 gridview 中的第一个 ImageView 上。所有其他工作都很好。
我在 Android View 源代码中四处寻找线索 - 为我的设备找到构建/标签是反复试验,但我发现 startDrag 中第 16281 行的少数几个之一是标签 jb-mr1-release(我的 Nexus 10 是4.2.1 所以它可能是正确的)。16281处的代码是:
Point shadowSize = new Point();
Point shadowTouchPoint = new Point();
shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
(shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
throw new IllegalStateException("Drag shadow dimensions must not be negative");
}
if (ViewDebug.DEBUG_DRAG) {
Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
+ " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
}
Surface surface = new Surface();
try {
IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
flags, shadowSize.x, shadowSize.y, surface);
if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
+ " surface=" + surface);
第 16281 行是 try 中的第一条语句:IBinder token = mAttachInfo.mSession ...
如果我的调查是正确的(我有正确的 JB/View.java 源),那么问题似乎在于 mAttachInfo 或其字段之一为空。shadowSize 之前已经过审查,并且刚刚创建了表面。第一个视图没有“mAttachInfo”值是否有某种原因(假设它没有附加到窗口)?或者它可能是 try 块中的其他行(异常被捕获)。