Fresco: Images dissapear after scrolling RecylcerView

旧街凉风 提交于 2019-12-12 16:05:07

问题


I have a Horizontal RecyclerView: each item has an image loaded into it using the Facebook Fresco image library. However, while the correct image loads initially as it is scrolled a bit onto the screen, it disappears when the RecyclerView is scrolled further.

In addition, there are issues where scrolling back and forth puts the wrong image in the wrong item (I assume this is an issue with recycling the viewholders). That said, the text you can see overlaying the items in the below screen shot always displays consistently on the correct item, so this recycling issue is exclusive to the images.

I can confirm I am passing the SimpleDraweeView the correct URL each time.

Below are some screens and accompanying logs:

Screenshot 1: showing the correct image entering from the right.

Logs as this is scrolled onto the screen and the image is successfully loaded:

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: com.facebook.drawee.generic.GenericDraweeHierarchy@d36ab12
AbstractDraweeController: controller 87baf9c null -> 9: initialize
AbstractDraweeController: controller c077610 8: setHierarchy: null
AbstractDraweeController: controller 87baf9c 9: setHierarchy: com.facebook.drawee.generic.GenericDraweeHierarchy@d36ab12
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

Screenshot 2: showing the RecyclerView after scrolling further from right to left. This shows the image that was previously loaded into the ViewHolder has now disappeared.

The following logs are produced between Screenshot 1 and 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

Code: 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>

Code: SimpleDraweeView setup

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

Code: 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)));
}
Thank you for your time if you got this far. Please let me know if further details could be useful and I will try to supply them.

Thanks again.


回答1:


From the logcat you can see that you are using the same instance of DraweeHierarchy with multiple controllers. Do not do that.

AbstractDraweeController: controller c077610 8: setHierarchy: com.facebook.drawee.generic.GenericDraweeHierarchy@d36ab12
AbstractDraweeController: controller 87baf9c null -> 9: initialize
AbstractDraweeController: controller c077610 8: setHierarchy: null
AbstractDraweeController: controller 87baf9c 9: setHierarchy: com.facebook.drawee.generic.GenericDraweeHierarchy@d36ab12

As explained in the documentation, do not re-use DraweeHierarchies. Each DraweeView needs to have its own instance of a DraweeHierarchy. Do not store the hierarchy in mHierarchy, just set the hierarchy to the view.

Also, each view needs its own hierarchy but that doesn't mean you have to build a new hierarchy each time you want to set a new image. You build the hierarchy only once, when you create the view and that's it. Later on when you need to set/change an image, just set a new controller to the view.

From your example it seems that you do not need to build the hierarchy programmatically at all. You can specify both the fade duration and the placeholder in XML. Btw, default value for fade-duration is 300ms so you can actually omit that part too. So, just remove the code that builds and sets the hierarchy (mDraweeView.setHierarchy(mHierarchy)).

If you are only using the Uri without any additional options, you do not need to build the controller. Just do mDraweeView.setImageURI(uri) and SimpleDraweeView will create the controller for you.



来源:https://stackoverflow.com/questions/34711792/fresco-images-dissapear-after-scrolling-recylcerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!