【问题标题】:How to play animated GIF image from url in android?如何在 android 中从 url 播放动画 GIF 图像?
【发布时间】:2014-12-29 23:34:27
【问题描述】:

我正在将 giphy 集成到我的 android 应用中..

如何在 Android 中播放来自 URL 的 animated gif 图像?我应该使用ImageView, WebView, VideoView 等吗?例如,如果我想从this URL 播放动画。

【问题讨论】:

标签: android image animation gif giphy


【解决方案1】:

只需创建一个 html 字符串并将其加载到 android webview 中。经过测试的解决方案。

http://developer.android.com/reference/android/webkit/WebView.html#loadData(java.lang.String, java.lang.String, java.lang.String)

 String x = "<!DOCTYPE html><html><body><img src=\"http://goo.gl/uPJ9P2\" alt=\"Smileyface\" width=\"100%\" height=\"100%\"></body></html>";

 webView.loadData(x, "text/html", "utf-8");   

【讨论】:

  • 这样我应该把 url 放在 String x=" giphy.com/gifs/funny-cat-DFiwMapItOTh6</body></…>"
  • 你能写出我应该在字符串 x 中放什么吗?你上面给出的代码没有开始的正文标签,但有一个结束的正文标签?并且是 img 一个标签?谢谢你时间...
  • @user3753273 立即查看
  • String x = "giphy.com/gifs/funny-cat-DFiwMapItOTh6" width="200" height="200">";我试过了,但它在代码“插入”中显示错误;“完成LocalVariableDeclarationStatement”..可能是因为引号..如果我删除所有引号应用程序运行但它显示空白webview...我是否应该使用引号..我更新鲜了..谢谢你的时间...
  • 如果我复制粘贴你的代码也显示语法错误,插入“;”完成 LocalVariableDeclarationStatement
【解决方案2】:

试试这个方法

    Movie movie;
    GifView(Context context) {
        super(context);
        movie = Movie.decodeStream(
                context.getResources().openRawResource(
                        R.drawable.some_gif));
    }
    @Override
    protected void onDraw(Canvas canvas) {   
        if (movie != null) {
            movie.setTime(
                (int) SystemClock.uptimeMillis() % movie.duration());
            movie.draw(canvas, 0, 0);
            invalidate();
        }
    }

【讨论】:

  • 我想从 url 播放..我应该用 url 替换 R.drawable.some_gif 吗?
【解决方案3】:

我建议使用可以支持 GIF 的第三方库,例如 Glide

我制作了一个快速示例应用程序,用于显示来自 Giphy 的 API here 的 GIF。

希望有帮助

【讨论】:

    【解决方案4】:

    解决方案的一般草图是使用自定义视图,该视图要求电影定期将自己绘制到画布上。

    第一步是构建 Movie 实例。有一个名为 decodeStream 的工厂可以在给定 InputStream 的情况下制作电影,但仅使用来自 UrlConnection 的流是不够的。如果你尝试这个,当电影加载器尝试在流上调用 reset 时,你会得到一个 IOException。不幸的是,黑客使用带有手动设置标记的单独 BufferedInputStream 来告诉它保存足够的数据以使重置不会失败。幸运的是,URLConnection 可以告诉我们需要多少数据。我说这种 hack 很不幸,因为它实际上需要将整个图像缓存在内存中(这对于桌面应用程序来说没有问题,但在内存受限的移动设备上却是一个严重的问题)。

    这是电影设置代码的片段:

    URL url = new URL(gifSource);
    URLConnection conn = url.openConnection();
    InputStream is = conn.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(is);
    bis.mark(conn.getContentLength());
    Movie movie = Movie.decodeStream(bis);
    bis.close();
    

    接下来,您需要创建一个显示该影片的视图。带有自定义 onDraw 的 View 子类可以解决问题(假设它可以访问您使用前面的代码创建的 Movie)。

    @Override protected void onDraw(Canvas canvas) {
        if(movie != null) {
            long now = android.os.SystemClock.uptimeMillis();
            int dur = Math.max(movie.duration(), 1); // is it really animated?
            int pos = (int)(now % dur);
            movie.setTime(pos);
            movie.draw(canvas, x, y);
        }
    }
    

    视图不会在没有帮助的情况下触发自身重绘,在 onDraw 结束时盲目调用 invalidate() 只是一种能源浪费。在另一个线程(可能是您用来下载图像数据的线程)中,您可以向主线程发布消息,要求以稳定(但不是疯狂)的速度使视图失效。

    Handler handler = new Handler();
    new Thread() {
        @Override public void run() {
            // ... setup the movie (using the code from above)
            // ... create and display the custom view, passing the movie
    
            while(!Thread.currentThread().isInterrupted()) {
                handler.post(new Runnable() {
                    public void run(){
                        view.invalidate();
                    }
                });
                try {
                    Thread.sleep(50); // yields 20 fps
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }.start();
    

    希望能帮助你理解

    【讨论】:

      猜你喜欢
      • 2017-10-03
      • 2016-04-06
      • 1970-01-01
      • 2012-07-10
      • 2012-08-24
      • 2011-11-14
      • 2016-12-17
      • 2012-03-18
      • 2012-02-26
      相关资源
      最近更新 更多