Mural: use the current image displayed in Drawee as a placeholder for the next request

I play several images sequentially on the same SimpleDraweeView , the problem is that when sending a new request imageURI SimpleDrweeView deletes the current displayed image and replaces it with nothing until the URI is loaded. That way, it will leave spaces in the playback sequence (you would think what I'm trying to do is a cartoony animation using local photos). What I would like for SimpleDrweeView to leave the current image until a new one is loaded, and then just change it when it is ready.

I tried using the low-res / high-res scheme from this ticket to set the old uri as a placeholder, but this did not work (it had the same effect as before).

This is what I have now:

  SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view); draweeView.setImageURI(uri /* local image */); 

And here is what I have tried so far (not working):

  SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view); Uri lowResUri, highResUri; DraweeController controller = Fresco.newDraweeControllerBuilder().setTapToRetryEnabled(true) .setLowResImageRequest(ImageRequest.fromUri((Uri) draweeView.getTag())) /*naive way to test the low/high res feature*/ .setImageRequest(ImageRequest.fromUri(uri)) .setOldController(draweeView.getController()) .build(); draweeView.setTag(uri); draweeView.setController(controller); 
+5
source share
1 answer

I am part of the Fresco team and can help. It is strange that you are experiencing the same problem with a combination of low resolution / high resolution. If the image is currently being displayed, this means that it must be in the cache of the raster memory, which, in turn, means that it should be able to immediately load when installing a low-resolution image the next time you switch to the next frame. Are you sure you are setting the correct uri as a low resolution image? (Uri) draweeView.getTag() looks suspicious. I would double check this part.

If Uri is really correct, but the image is not in the bitmap cache anymore, it would be worth investigating why the image that is visible is not cached anymore, since we have explicit logic in place that should prevent visible images from being evicted. See how to track this with detailed logging here .

If all of the above fails, the third option is to actually implement your own DataSource . I can help with this, but it can be somewhat involving. The basic idea is to implement a DataSource that wraps another DataSource that actually provides the image. Then you can do something like this:

 // keep this instance somewhere mMyDataSourceSupplier = new MyDataSourceSupplier(); // build controller by specifying your custom datasource supplier instead of specifying any URIs. Fresco.newDraweeControllerBuilder() .setDataSourceSupplier(mMyDataSourceSupplier) .build() // later, when you need to change the image do mMyDataSourceSupplier.setUri(nextUri); // this is just an outline class MyDataSourceSupplier implements Supplier<DataSource<CloseableReference<CloseableImage>>> { private Uri mCurrentUri; private DataSource<CloseableReference<CloseableImage>> mCurrentDataSource; public void setUri(Uri uri) { mCurrentUri = uri; if (mCurrentDatasource != null) { mCurrentDataSource.setUri(uri); } } @Override public DataSource<CloseableReference<CloseableImage>> get() { mCurrentDataSource = new MyDataSource(); mCurrentDataSource.setUri(uri); return mCurrentDataSource; } private class MyDataSource extends AbstractDataSource<CloseableReference<CloseableImage>> { private DataSource mUnderlyingDataSource; @Override protected void closeResult(@Nullable CloseableReference<CloseableImage> result) { CloseableReference.closeSafely(result); } @Override @Nullable public CloseableReference<CloseableImage> getResult() { return CloseableReference.cloneOrNull(super.getResult()); } @Override public boolean close() { if (mUnderlyingDataSource != null) { mUnderlyingDataSource.close(); mUnderlyingDataSource = null; } return super.close(); } public void setUri(Uri uri) { if (mUnderlyingDataSource != null) { mUnderlyingDataSource.close(); mUnderlyingDataSource = null; } if (uri != null && !isClosed()) { mUnderlyingDataSource = Fresco.getImagePipeline().fetchDecodedImage(ImageRequest.fromUri(uri), null); mUnderlyingDataSource.subscribe(new BaseDataSubscriber { @Override protected void onNewResultImpl(DataSource<List<CloseableReference<CloseableImage>>> dataSource) { MyDataSource.super.setResult(dataSource.getResult(), false); } }); } } } } 
+3
source

Source: https://habr.com/ru/post/1236931/


All Articles