I play multiple images sequentially on the same SimpleDraweeView
, the issue is that when submitting a new imageURI request, theSimpleDrweeView
will remove the current displayed image and replace it with nothing until the URI is downloaded. So it will leave gaps in the playing sequence ( you could think of what I'm trying to do is cartoon animation using local photos). What I would like for the SimpleDrweeView to leave the current image as is until the new one is downloaded and then just swap it when it's ready.
I tried using the low-res/high-res scheme from this ticket to put the old uri as a placeholder but that didn't work (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 this is what I tried so far (didn't work):
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);
I am part of the Fresco team and may be able to help.
It is strange that you experience the same issue with low-res/high-res combination. If the image is currently displayed, it means it should be in the bitmap memory cache, which in turn means that it should be able to load immediately when set as a low-res image the next time you are switching to the next frame.
Are you sure that you are setting the correct uri as low-res image? (Uri) draweeView.getTag()
looks kind of suspicious. I would double check that part.
If the uri is indeed 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, as we have explicit logic in place that should prevent evicting visible images. See how to track this with verbose logging here.
If all of the above fails, third options is to actually implement your own DataSource. I can help with that, but this might be somewhat involving. The basic idea is to implement a DataSource
that wraps another DataSource
that actually provides the image. Then you could 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);
}
});
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With