2013-08-16 7 views
7

Mam GridView. Każdy element w widoku GridView jest układem poziomym (lub pionowym) (w zależności od orientacji). Wewnątrz tego układu znajduje się ImageView i TextView.Po onLongPress, pierwszy widok w widoku siatki pobiera NullPointerException w startDrag

Kiedy wykonuję "Long Touch" na dowolnym ImageView innym niż pierwszy w GridView, wszystko działa zgodnie z planem. W procedurze obsługi onLongPress() wywołuję startDrag na ImageView i wszystko działa zgodnie z planem. Jeśli wykonuję "Long Touch" na pierwszym ImageView w GridView, otrzymam wyjątek NullPointer w metodzie startUrag() Android View.

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) 

byłem w stanie sprawdzić, czy wszystko z argumentów przekazanych do startDrag były non-null - ClipData, A DragShadowBuilder, a mój ImageView jako LocalState. Oto, że fragment kodu:

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

startDrag zwraca false i logcat zawiera Nie można uruchomić komunikat przeciągania i ślad wyjątku.

Dzieje się tak tylko przy pierwszym ImageView w widoku siatki. Wszystkie inne działają dobrze.

Sprawdziłem źródło Androida, szukając wskazówek - znalezienie wersji/tagu dla mojego urządzenia było próbą i błędem, ale jednym z niewielu, które znalazłem, gdzie linia 16281 była w startDrag, była etykieta jb-mr1-release (mój Nexus 10 to 4.2.1, więc może być odpowiedni). Kod na 16281 wynosi:

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

Linia 16281 to pierwsza wypowiedź w try: IBinder żeton = mAttachInfo.mSession ...

Jeśli moja sleuthing jest prawidłowe (mam prawo JB/Widok. java source), wydaje się, że problem jest związany z mAttachInfo lub jednym z jego pól o wartości null. shadowSize został wcześniej sprawdzony, a powierzchnia została właśnie stworzona. Czy jest jakiś powód, dla którego pierwszy widok nie miałby wartości "mAttachInfo" (zakładając, że nie jest on dołączony do okna)? Lub jest możliwe, że jest to inna linia w bloku try (wyjątek zostaje złapany).

+0

Błąd może być RemoteLauncher.java:650. Co jest szczególnego na tej linii? – Nizam

+0

To byłaby prośba startDrag w powyższym kodzie: DragShadowBuilder shadowBuilder = new View.DragShadowBuilder (mView); – BJV

+0

następnie 'mView' ma wartość zerową. – Nizam

Odpowiedz

0

Widok # startDrag wyrzuci NPE, jeśli widok nie jest dołączony.

Zobacz # isAttachedToWindow może powiedzieć, czy widok jest dołączony, czy nie, ale ta metoda jest dostępna tylko na KITKAT.

Zgłaszałbym błąd.

1

Napotkałem ten problem. Obmyśliłem go, dodając ImageView, który zawierał obraz widoku i używał go tak, jakbym przeciągał oryginalny widok i działał.

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

To może zadziałać, ale zrezygnowałem i przełączyłem się z GridView na używanie list linearnych. Odkąd ustaliłem/próbowałem, nie chcę dać ci "zielonego czeku". Jeśli ktoś spróbuje tego i działa, daj mi znać, a ja to sprawdzę. – BJV

0

wiem, że to jest stary, ale wpadłem na dokładnie tej kwestii. W moim niestandardowego adaptera Starałem się, aby elementy kwadratowe, więc robię coś

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

co pracował dla mnie jest

imageView.getLayoutParams().width = width; 
imageView.getLayoutParams().height = width; 
Powiązane problemy