2016-01-10 127 views
3

我有一個水平RecyclerView:每個項目都有一個圖像加載到它使用Facebook Fresco圖像庫。然而,當正確的圖像在屏幕上滾動一點時,最初加載的圖像會在RecyclerView進一步滾動時消失。壁畫:滾動後圖像消失RecylcerView

此外,有來回滾動將錯誤的圖像放在錯誤的項目(我認爲這是回收視圖的問題)的問題。也就是說,您可以看到覆蓋下面屏幕截圖中的項目的文字始終顯示在正確的項目上,因此此回收問題對圖像是獨有的。

我可以確認我每次都傳遞SimpleDraweeView正確的URL。

下面是一些屏幕和伴隨的日誌:

screenshot one, showing the image entering from the right

截圖1:顯示正確的圖像從右側進入。

日誌,因爲這被滾動到屏幕上,並且圖像被成功加載:

AbstractDraweeController: controller cbb6b5b 5: onTouchEvent MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=32.860107, y[0]=198.16406, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=464189, downTime=464189, deviceId=0, source=0x1002 } 
 
AbstractDraweeController: controller c077610 8: setHierarchy: [email protected] 
 
AbstractDraweeController: controller 87baf9c null -> 9: initialize 
 
AbstractDraweeController: controller c077610 8: setHierarchy: null 
 
AbstractDraweeController: controller 87baf9c 9: setHierarchy: [email protected] 
 
AbstractDraweeController: controller 87baf9c 9: onAttach: request needs submit 
 
PipelineDraweeController: controller 87baf9c: getDataSource 
 
AbstractDraweeController: controller 87baf9c 9: submitRequest: dataSource: ad37da5 
 
BufferedDiskCache: Did not find image for http://i.imgur.com/OVwFM9ub.jpg in staging area 
 
BufferedDiskCache: Disk cache read for http://i.imgur.com/OVwFM9ub.jpg 
 
BufferedDiskCache: Found entry in disk cache for http://i.imgur.com/OVwFM9ub.jpg 
 
NativeMemoryChunkPool: Used = (7, 188416); Free = (0, 0) 
 
NativeMemoryChunkPool: get (alloc) (object, size) = (ef2f57a, 16384) 
 
GenericByteArrayPool: Used = (1, 16384); Free = (0, 0) 
 
GenericByteArrayPool: get (reuse) (object, size) = (cf34727, 16384) 
 
GenericByteArrayPool: release (reuse) (object, size) = (cf34727, 16384) 
 
GenericByteArrayPool: Used = (0, 0); Free = (1, 16384) 
 
BufferedDiskCache: Successful read from disk cache for http://i.imgur.com/OVwFM9ub.jpg 
 
TiffUtil: Unsupported orientation 
 
BitmapPool: Used = (7, 2831360); Free = (0, 0) 
 
BitmapPool: get (alloc) (object, size) = (8622988, 102400) 
 
AbstractDraweeController: controller 87baf9c 9: set_final_result @ onNewResult: image: CloseableReference 1a34f21

enter image description here

截圖2:示出了從右側進一步滾動後的RecyclerView到左。這顯示以前加載到ViewHolder中的圖像現在已經消失。

以下日誌截圖1和2之間產生的:

AbstractDraweeController: controller cbb6b5b 5: onTouchEvent MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=103.65283, y[0]=144.14063, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=793409, downTime=793409, deviceId=0, source=0x1002 } 
 
AbstractDraweeController: controller 87baf9c 9: onDetach 
 
AbstractDraweeController: controller e14aa9d 2: onDetach 
 
AbstractDraweeController: controller 87baf9c 9: release: image: CloseableReference 1a34f21 
 
AbstractDraweeController: controller e14aa9d 2: release: image: CloseableReference 61f0be9

代碼: ViewHolder XML

<?xml version="1.0" encoding="utf-8"?> 
 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:fresco="http://schemas.android.com/apk/res-auto" 
 
    android:layout_width="120dp" 
 
    android:layout_height="match_parent" 
 
    android:background="#993366"> 
 

 
    <com.facebook.drawee.view.SimpleDraweeView 
 
     android:id="@+id/recycler_drawee_view" 
 
     android:layout_width="110dp" 
 
     android:layout_height="match_parent" 
 
     android:background="#336699" 
 
     fresco:placeholderImage="@drawable/placeholder" /> 
 

 
    <TextView 
 
     android:id="@+id/recycler_text_view" 
 
     android:layout_width="wrap_content" 
 
     android:layout_height="wrap_content" 
 
     android:text="TEST" /> 
 

 
</FrameLayout>

代碼:SimpleDraweeView設置

GenericDraweeHierarchyBuilder builder = 
 
       new GenericDraweeHierarchyBuilder(context.getResources()); 
 
mHierarchy = builder 
 
     .setFadeDuration(300) 
 
     .setPlaceholderImage(context.getDrawable(R.drawable.placeholder)) 
 
     .build(); 
 

 
... 
 

 
mDraweeView.setHierarchy(mHierarchy); 
 
Uri uri = Uri.parse(imageLink); 
 
DraweeController controller = Fresco.newDraweeControllerBuilder() 
 
.setUri(uri) 
 
.build(); 
 
mDraweeView.setController(controller);

代碼:RecyclerView.Adapter

@Override 
 
public SimpleHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
 
View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_item, viewGroup, false); 
 
return new SimpleHolder(view, mHierarchy); 
 
} 
 

 
... 
 

 
@Override 
 
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { 
 
holder.setText(EntryUtils.getFullCaption(mData.get(position))); 
 
holder.setImage(EntryUtils.getThumbnailLink(mData.get(position))); 
 
}
謝謝您的時間,如果你走到這一步。請讓我知道,如果進一步的細節可能是有用的,我會盡力提供。

再次感謝。

回答

2

從logcat中,您可以看到您正在使用具有多個控制器的DraweeHierarchy的相同實例。不要那樣做。

AbstractDraweeController: controller c077610 8: setHierarchy: [email protected] 
AbstractDraweeController: controller 87baf9c null -> 9: initialize 
AbstractDraweeController: controller c077610 8: setHierarchy: null 
AbstractDraweeController: controller 87baf9c 9: setHierarchy: [email protected] 

正如documentation解釋,不要再使用DraweeHierarchies。每個DraweeView都需要有自己的DraweeHierarchy實例。不要將層次結構存儲在mHierarchy中,只需將層次結構設置爲視圖即可。

此外,每個視圖都需要自己的層次結構,但這並不意味着每次要設置新圖像時都必須構建新的層次結構。只有在創建視圖時才構建一次層次結構,就是這樣。稍後,當您需要設置/更改圖像時,只需在視圖中設置一個新的控制器即可。

從你的例子看來,你不需要編程構建層次結構。您可以在XML中指定淡入淡出持續時間和佔位符。順便說一句,淡入持續時間的默認值是300毫秒,所以你實際上可以省略那部分。 因此,只需刪除構建和設置層次結構的代碼(mDraweeView.setHierarchy(mHierarchy))。

如果您只使用Uri而沒有任何其他選項,則無需構建控制器。只要做mDraweeView.setImageURI(uri)SimpleDraweeView會爲你創建控制器。

+0

謝謝,重用Hierarchy是個問題!我之前閱讀過文檔,聲明不重建層次結構,但我誤解並且只構建了一次,並將其重用於所有視圖,而不是每個視圖的一個層次結構。 此外,.setImageUri(uri)已棄用。我認爲建議不管使用控制器,但我可能是錯的。再次感謝! – ITJscott