2013-08-16 46 views
7

Tôi có một GridView. Mỗi mục trong GridView là một Horizontal (hoặc Vertical) Layout (tùy theo hướng). Bên trong bố cục đó là một ImageView và một TextView.Sau khi onLongPress, xem đầu tiên trong GridView được NullPointerException trong startDrag

Khi tôi thực hiện "Long Touch" trên bất kỳ ImageView nào khác với ảnh đầu tiên trong GridView, mọi thứ hoạt động như được lên kế hoạch. Trong trình xử lý onLongPress(), tôi gọi startDrag trên ImageView và mọi thứ hoạt động như kế hoạch. Nếu tôi thực hiện một "Long Touch" trên ImageView đầu tiên trong GridView, tôi nhận được ngoại lệ NullPointer trong phương thức startDrag() của 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) 

Tôi đã có thể xác minh rằng tất cả các đối số được truyền cho startDrag là không null - một ClipData, một DragShadowBuilder và ImageView của tôi làm LocalState. Đây là đoạn mã:

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

startDrag trả về false và logcat chứa Không thể bắt đầu kéo thư và theo dõi ngoại lệ.

Điều này chỉ xảy ra trên ImageView đầu tiên trong chế độ xem lưới. Tất cả những người khác làm việc tốt.

Tôi chọc xung quanh nguồn Android View tìm kiếm manh mối - việc tìm kiếm thẻ xây dựng/thiết bị của tôi đã được thử và lỗi nhưng một trong số ít tôi đã tìm thấy dòng 16281 ở startDrag với thẻ jb-mr1-release (Nexus 10 của tôi là 4.2.1 nên có thể là thiết bị phù hợp). Mã tại 16.281 là:

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

Dòng 16.281 là tuyên bố đầu tiên trong thử: IBinder thẻ = mAttachInfo.mSession ...

Nếu sleuthing của tôi là chính xác (tôi có quyền JB/View. nguồn java), nó sẽ xuất hiện rằng vấn đề là với mAttachInfo hoặc một trong các lĩnh vực của nó là null. shadowSize đã được đánh dấu trước đó và bề mặt vừa được tạo ra. Có một số lý do tại sao Chế độ xem đầu tiên sẽ không có giá trị "mAttachInfo" (giả sử nó có nghĩa là nó không được gắn với một cửa sổ)? Hoặc có thể là một số dòng khác trong khối thử (ngoại lệ bị bắt).

+0

Lỗi có thể ở RemoteLauncher.java:650. Có gì cụ thể trên dòng đó? – Nizam

+0

Đó sẽ là cuộc gọi để startDrag trong mã ở trên: DragShadowBuilder shadowBuilder = new View.DragShadowBuilder (mView); – BJV

+0

thì 'mView' là rỗng ở đó. – Nizam

Trả lời

0

Xem # startDrag sẽ ném NPE nếu Chế độ xem không được đính kèm.

Chế độ xem # isAttachedToWindow có thể cho bạn biết xem chế độ xem có được đính kèm hay không nhưng phương pháp này chỉ khả dụng trên KITKAT.

Tôi sẽ gửi lỗi.

1

Tôi cũng gặp sự cố này. Tôi đã làm việc xung quanh nó bằng cách thêm một ImageView có chứa một hình ảnh của khung nhìn và sử dụng nó như tôi sẽ có cái nhìn ban đầu được kéo và nó đang làm việc.

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

Điều này có thể hiệu quả, nhưng tôi đã từ bỏ và chuyển từ sử dụng GridView sang sử dụng danh sách tuyến tính. Kể từ khi tôi đang sửa chữa/thử nó, tôi do dự để cung cấp cho bạn "kiểm tra màu xanh lá cây". Nếu bất cứ ai khác cố gắng điều này và nó hoạt động, hãy cho tôi biết và tôi sẽ kiểm tra nó đi. – BJV

0

Tôi biết điều này là cũ, nhưng tôi đã gặp sự cố chính xác này. Trong bộ chuyển đổi tùy chỉnh của tôi, tôi đã cố gắng để thực hiện các mục vuông, vì vậy tôi đang làm một cái gì đó giống như

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

gì làm việc cho tôi là

imageView.getLayoutParams().width = width; 
imageView.getLayoutParams().height = width; 
Các vấn đề liên quan