2013-08-16 9 views
7

我有一個GridView。 GridView中的每個項目都是水平(或垂直)佈局(取決於方向)。該佈局內部是一個ImageView和一個TextView。在onLongPress之後,gridview中的第一個視圖在startDrag中獲取NullPointerException

當我在任何ImageView上執行「Long Touch」時,除GridView中的第一個外,所有內容都按計劃運行。在onLongPress()處理程序中,我調用ImageView上的startDrag,並且一切按計劃進行。如果我在GridView的第一個ImageView上執行「Long Touch」,我會在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,並作爲LocalState我ImageView的。這裏是代碼片段:

ClipData data = ClipData.newPlainText("", ""); 
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(mView); 
boolean doingDrag = mView.startDrag(data, shadowBuilder, mView, 0); 

startDrag返回false,並且logcat包含無法啓動拖動消息和異常跟蹤。

這隻發生在gridview中的第一個ImageView上。所有其他人工作得很好。

我繞過Android View源尋找線索 - 發現我的設備的構建/標記是試驗和錯誤,但我發現其中少數線路16281在startDrag中的一個是標記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是在嘗試的第一條語句:令牌的IBinder = mAttachInfo.mSession ...

如果我的偵探是正確的(我有權利JB /視圖。 java源代碼),那麼問題出現在mAttachInfo或其中一個字段爲空。 shadowSize已經過審查,表面剛創建。是否有一些原因,爲什麼第一個視圖不會有「mAttachInfo」值(假設它意味着它沒有連接到窗口)?或者它可能是try塊內的其他行(異常被捕獲)。

+0

錯誤可能是在RemoteLauncher.java:650。那條線上具體是什麼? – Nizam

+0

這將是上面代碼中對startDrag的調用: DragShadowBuilder shadowBuilder = new View。DragShadowBuilder(MVIEW); – BJV

+0

那麼'mView'在那裏是空的。 – Nizam

回答

0

如果視圖未附加,View#startDrag將拋出NPE。

查看#isAttachedToWindow可以告訴你該視圖是否附加,但此方法僅適用於KITKAT。

我想提交一個bug。

1

我也遇到過這個問題。我通過添加一個包含視圖圖像的ImageView來解決它,並使用它,因爲我會拖動原始視圖並且它正在工作。

Bitmap b = Bitmap.createBitmap(originalView.getWidth(), originalView.getHeight(), Bitmap.Config.ARGB_8888); 


Canvas c = new Canvas(b); 
      originalView.draw(c); 
      mImageView.setImageBitmap(b); 
shadowBuilder = new View.DragShadowBuilder(mImageView); 
        mImageView.startDrag(data, shadowBuilder, mImageView, 0); 
        mImageView.setVisibility(View.INVISIBLE); 
+0

這可能會起作用,但我放棄了使用GridView切換到使用線性列表。由於我正在修理/嘗試它,所以我不願意給你「綠色檢查」。如果其他人嘗試這種方式,它的工作原理,讓我知道,我會檢查它。 – BJV

0

我知道這是舊的,但我遇到了這個確切的問題。 在我的自定義適配器,我試圖讓項目方,所以我做這樣的事情

imageView.setLayoutParams(new AbsListView.LayoutParams(width, width)); 

什麼工作對我來說是

imageView.getLayoutParams().width = width; 
imageView.getLayoutParams().height = width; 
相關問題