Fresco:将当前在Drawee中显示的图像用作下一个请求的占位符

7

我在同一个SimpleDraweeView上按顺序播放多个图像,问题是当提交新的imageURI请求时,SimpleDrweeView将删除当前显示的图像,并用空白替换它,直到URI被下载。因此,它会在播放序列中留下空白(您可以认为我正在尝试使用本地照片制作卡通动画)。我希望SimpleDrweeView在新图像下载完成之前保留当前图像,然后在准备好时进行交换。

我尝试使用票证中的低分辨率/高分辨率方案将旧的uri作为占位符,但这没有起作用(与以前的效果相同)。

这是我现在拥有的:

 SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);

 draweeView.setImageURI(uri /* local image */); 

这是我尝试过的(但没有成功):
                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); 
1个回答

3
我是Fresco团队的一员,可以提供帮助。 如果您在低分辨率/高分辨率组合下遇到了相同的问题,这很奇怪。如果图像当前正在显示,则应该位于位图内存缓存中,这意味着在设置为下一个低分辨率图像时,它应该能够立即加载。 您确定正在将正确的uri作为低分辨率图像进行设置吗?(Uri) draweeView.getTag()看起来有些可疑。我建议您再次检查这一部分。
如果uri确实正确,但是图像不再位于位图缓存中,最好调查一下为什么可见的图像不再被缓存,因为我们已经明确地采取了措施防止清除可见图像。 请参考此处以详细记录日志:here
如果以上所有方法都失败了,第三个选择就是实际上要实现自己的DataSource。我可以提供帮助,但这可能有些复杂。基本想法是实现一个包装另一个实际提供图像的 DataSource DataSource 。然后您可以像这样操作:
// 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);
          }
        });
      }
    }
  }
}

1
非常感谢这个。我下周会尝试一下,并会告诉您结果。 - Jimmy
@plamenko 为什么你决定在加载新图片时隐藏现有图片?提供选择隐藏或不隐藏似乎更加有用。 - Anton Malyshev
@AntonMalyshev,我们决定不是要隐藏现有的图片。这实际上是Drawee设计的结果。Drawee从DataSource获取显示图像(该DataSource又来自Supplier<DataSource>)。Drawee只有一个供应商,这大大简化了设计,因为混合逻辑封装在那里,而不是在Drawee控制器中。使用Drawee实现此功能的一种干净方法是使用执行此操作的供应商。 - plamenko
@AntonMalyshev,...所以你的问题应该更准确地表述为“为什么Fresco没有提供这样的供应商?”答案很简单,当时并没有这个需求。我们欢迎拉取请求,如果提供的供应商足够通用且常见,我们将很乐意将其与Fresco一起发布。 - plamenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接