【问题标题】:Show Gif preview with Fresco on Android (as first frame, for instance)在 Android 上使用 Fresco 显示 Gif 预览(例如,作为第一帧)
【发布时间】:2017-03-13 19:48:26
【问题描述】:

我使用 Fresco 库在 RecyclerView 和 android 中显示动画 gif 文件。 我的代码很简单,我在 onBindViewHolder() 中执行此操作:

 DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(url)
                .setAutoPlayAnimations(true)
                .build();
 simpleDraweeView.setController(controller);

一切都很好,但是当我向上或向下滚动时,似乎 GIF 图像没有被缓存和重新加载。所以我决定像简单的图像一样显示 GIF 文件的预览。 ImageRequest 的 setLocalThumbnailPreviewsEnabled(true) 似乎不适用于 GIF 图像。 然后我尝试将 ImageDecodeOptionsBuilder 与 setForceStaticImage(true) 一起使用 - 它将 GIF 显示为静态图像(几乎是我需要的,但我需要在加载静态图像后启动动画)。 这是我所有的代码:

    Uri imageUri = Uri.parse(url);
    ImageDecodeOptionsBuilder decodeOptionsBuilder = new ImageDecodeOptionsBuilder();
    decodeOptionsBuilder.setForceStaticImage(true);
    decodeOptionsBuilder.setDecodePreviewFrame(true);
    ImageDecodeOptions imageDecodeOptions = new ImageDecodeOptions(decodeOptionsBuilder);
    ImageRequest request =  ImageRequestBuilder.newBuilderWithSource(imageUri)
            .setImageDecodeOptions(imageDecodeOptions)
            .setLocalThumbnailPreviewsEnabled(true)
            .build();

    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setImageRequest(request)
            .setAutoPlayAnimations(true)
            .build();
    simpleDraweeView.setController(controller);

我也尝试过使用 setAutoPlayAnimations(true/false) 和其他参数(如 decodeOptionsBuilder.setDecodePreviewFrame(true)),但仍然没有成功。

所以我的问题是:如何将静态图像显示为 GIF 的预览图像(如占位符)?如果它是 GIF 的第一个(或其他)帧,那就太酷了。任何帮助表示赞赏。

【问题讨论】:

    标签: android gif animated-gif fresco


    【解决方案1】:

    按照您的描述,最简单的方法是:

    在您强制使用静态图像的位置设置 GIF。 一旦你想播放动画(例如点击),再次设置图像,但这次使用setAutoPlayAnimations

    作为替代方案,您也可以不自动启动动画,而是在点击时启动它,请参阅https://github.com/facebook/fresco/blob/master/samples/animation/src/main/java/com/facebook/samples/animation/MainActivity.java#L131

    基本上,您可以像这样构建控制器:

    DraweeController gifController = Fresco.newDraweeControllerBuilder()
        .setUri(animatedGifUri)
        .setControllerListener(new BaseControllerListener<ImageInfo>() {
          @Override
          public void onFinalImageSet(
              String id,
              ImageInfo imageInfo,
              Animatable anim) {
            if (anim != null) {
              // start the animation with anim.start() whenever you want
            }
          }
        })
        .build();
    

    很遗憾,目前没有更好的方法来做到这一点。不过,我们正在考虑在未来改进 Fresco 的动画 API。

    【讨论】:

    • 嗨,亚历山大,谢谢您的回答。基本上,我想使用 setAutoPlayAnimations(true) 并自动开始播放 GIF 动画。例如,它应该像在 giphy 应用程序中(不是在点击时启动它) - play.google.com/store/apps/details?id=com.giphy.messenger 。当然,可能他们使用了其他一些图像加载器库,但我想使用 fresco(我更喜欢它)并实现类似的行为。关于壁画,当我向上/向下滚动时,我看到的是占位符而不是图像。我更喜欢看 GIF,但是好吧,假设我只想看静态图像(*.jpeg、.png 等)。
    • 它可能是来自 GIF 的一些帧作为选项。所以你的意思是现在不可能用 fresco 以这种方式实现它?也许有一种方法可以在加载静态图像后(使用 onFinalImageSet() 或其他东西)以某种方式将 SimpleDraweeView 中的静态图像更改为 GIF?或者在同一位置为 GIF 使用第二个 SimpleDraweeView,使其可见并稍后启动动画(在用户停止滚动后)?
    • 所以对我来说,我只看到彩色占位符,然后是 giphy 的 GIF。这可以通过一个简单的颜色占位符drawable来完成。备选方案 1:只要您愿意,只需手动启动动画(例如,当视图在屏幕上显示一段时间时 - 请参阅我上面的解决方案以了解如何执行此操作)。备选方案 2:设置一个关闭动画的 lowResImageUri 和一个打开动画的普通的。但是,我看不出这样做有什么好处。
    • 备选方案 1 不适合我,因为我需要尽快开始动画(但我希望看到静态图像而不是彩色占位符)。所以 setAutoPlayAnimations(true) 就是我需要的。就我而言,替代方案 2(几乎)是不可能的,因为我使用 giphy api 来制作 GIF。看起来我无法通过此 API 获取 GIF 的缩略图 *.jpeg 或 *.png 图像。所以我需要以某种方式制作 thumbmail *.jpeg 或 *.png 图像,然后显示它们。实际上,我想“使用 GIF 中的第一帧(或其他帧)作为 GIF 图像的占位符图像”这一功能会很有用。
    • 不幸的是,我对 GIF 和 fresco 源代码不是很熟悉,无法进行一些改进或帮助您。而且我知道实施起来并不容易。我想会有另一个问题——我们必须在哪里存储这个静态图像(或帧)以及如何缓存它。无论如何,感谢您的工作和帮助,我非常感谢。我不会将此问题标记为已解决,我将在以后返回并尝试为我找到一些可接受的解决方案。
    猜你喜欢
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2016-08-27
    • 2019-02-22
    • 1970-01-01
    • 2023-03-28
    • 2014-02-21
    相关资源
    最近更新 更多