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

1 回答 1

3

我是 Fresco 团队的一员,也许可以提供帮助。奇怪的是,您在使用低分辨率/高分辨率组合时遇到了同样的问题。如果图像当前显示,则意味着它应该在位图内存缓存中,这反过来意味着当您下次切换到下一帧时,它应该能够在设置为低分辨率图像时立即加载。您确定将正确的 uri 设置为低分辨率图像吗?(Uri) draweeView.getTag()看起来有点可疑。我会仔细检查那部分。

如果 uri 确实正确,但图像不再在位图缓存中,那么值得研究为什么不再缓存可见图像,因为我们有明确的逻辑可以防止驱逐可见图像。在此处查看如何使用详细日志记录来跟踪这一点。

如果以上所有方法都失败了,第三种选择是实际实现您自己的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);
          }
        });
      }
    }
  }
}
于 2015-12-03T21:28:03.307 回答