显示动画GIF


261

我想在应用程序中显示GIF动画图像。正如我所发现的那样,Android本身并不支持GIF动画。

但是,它可以使用AnimationDrawable显示动画:

开发>指南>图像和图形> Drawables概述

该示例使用在应用程序资源中另存为帧的动画,但是我需要直接显示动画gif。

我的计划是将动画GIF分解为帧,并将每个帧作为可绘制对象添加到AnimationDrawable中。

有谁知道如何从GIF动画中提取帧并将其转换为Drawable


2
您是要在android中使用,还是要使用外部工具从gif提取帧?
奥斯蒙德2010年

这绝对是一个错误,有关更多信息,请参见IssueTracker
fbtb 2011年

只适合所有通过搜索可以显示GIF动画的应用程序来到这里的用户:quickPic
rubo77


使用壁画显示GIF github.com/facebook/fresco我认为这是一个简单的解决方案。
kaitian521 '16

Answers:


191

Android实际上可以使用android.graphics.Movie类解码并显示动画GIF。

没有太多文档记录,但是在SDK Reference中。此外,它在BitmapDecode示例的ApiDemos的Samples中使用了一些动画标记。


9
这有多稳定?我已经在我的应用中实现了它,在我的Ice Cream Sandwich设备上,它根本不起作用,在2.3仿真器上,它可以工作,但是某些GIF框架有错误(错误的颜色)。在计算机上,它当然可以正常工作。是什么赋予了?
Benoit Duffez'2

12
@Bicou在HC后的设备上,您应该setLayerType(LAYER_TYPE_SOFTWARE)在视图上。但是它仍然仅适用于某些gif和某些设备。
2013年

9
@MichałK谢谢!Paint p = new Paint(); p.setAntiAlias(true); setLayerType(LAYER_TYPE_SOFTWARE, p);工作了!
Chloe 2013年

1
@lubosz:LAYER_TYPE_SOFTWARE应该足以设置。
指针为空

2
电影类没有故意记录在案-它功能薄弱且不受支持。如果需要适当的Gif动画,则最好自己实现。我是使用NDK为我的应用程序完成的。
指针为空2014年

60

更新:

使用滑行:

dependencies {
  implementation 'com.github.bumptech.glide:glide:4.0.0'
}

用法:

Glide.with(context).load(GIF_URI).into(new GlideDrawableImageViewTarget(IMAGE_VIEW));

查看文件


1
现在对我来说看起来不错,显然答案不能包含整个库,因此调用示例似乎就足够了。
令人惊讶的2015年

@gaborous显然,在进行标记时未包含代码。
1

1
如果您已经在使用NDK,则不建议您使用此库。将这个库添加到gradle之后,Unity模块停止工作。
RominaV '16

这是我找到的最好的图书馆。我遇到的一件事是实施捏缩放gif图像。有人知道吗
毒蛇

28

也放(main / assets / htmls / name.gif)[用这个html调整大小]

<html style="margin: 0;">
<body style="margin: 0;">
<img src="name.gif" style="width: 100%; height: 100%" />
</body>
</html>

在您的Xml中声明这样的示例(main / res / layout / name.xml):[例如,您定义大小]

<WebView
android:layout_width="70dp"
android:layout_height="70dp"
android:id="@+id/webView"
android:layout_gravity="center_horizontal" />

在您的活动中,将下一个代码放在onCreate内

web = (WebView) findViewById(R.id.webView); 
web.setBackgroundColor(Color.TRANSPARENT); //for gif without background
web.loadUrl("file:///android_asset/htmls/name.html");

如果要动态加载,则必须使用数据加载Webview:

// or "[path]/name.gif" (e.g: file:///android_asset/name.gif for resources in asset folder), and in loadDataWithBaseURL(), you don't need to set base URL, on the other hand, it's similar to loadData() method.
String gifName = "name.gif";
String yourData = "<html style=\"margin: 0;\">\n" +
        "    <body style=\"margin: 0;\">\n" +
        "    <img src=" + gifName + " style=\"width: 100%; height: 100%\" />\n" +
        "    </body>\n" +
        "    </html>";
// Important to add this attribute to webView to get resource from outside.
webView.getSettings().setAllowFileAccess(true);

// Notice: should use loadDataWithBaseURL. BaseUrl could be the base url such as the path to asset folder, or SDCard or any other path, where your images or the other media resides related to your html
webView.loadDataWithBaseURL("file:///android_asset/", yourData, "text/html", "utf-8", null);
// Or if you want to load image from SD card or where else, here is the idea.
String base = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
webView.loadDataWithBaseURL(base + '/', yourData, "text/html", "utf-8", null);

建议:最好将gif与静态图片一起加载以获取更多信息,请检查https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

就是这样,希望您能对您有所帮助。


2
如果我想从sdcard加载GIF?
Jaydev '16

如果您要从sdcard加载:请替换“ file:///android_asset/htmls/name.html”作为图像的uri
Alex Zaraos

使用此方法,如何动态更改gif文件的名称?我不想让HTML文件与我需要在我的应用程序中显示的所有gif文件一起显示
scrayne's

GIF的Webview?!?您是否考虑过性能,内存消耗和电池?
杜纳(Duna)

@Duna是5年前,目前我们可以使用滑行
Alex Zaraos

22

我通过将gif动画拆分为帧来解决该问题,然后再将其保存到手机中,因此无需在Android中处理它。

然后我将每个帧下载到手机上,从中创建Drawable,然后创建AnimationDrawable-与我的问题中的示例非常相似


2
这是处理动画的记录方法。
RichieHH 2014年

16

我找到了一种非常简单的方法,这里有一个简单易用的示例

显示动画小部件

在开始工作之前,代码中需要做一些改动

在下面的

    @Override
    public void onCreate(Bundle savedInstanceState){    
        super.onCreate(savedInstanceStated);   
        setContentView(new MYGIFView());
    }    
}

只需更换

setContentView(new MYGIFView());

setContentView(new MYGIFView(this));

和在

public GIFView(Context context) {
    super(context);

提供自己的gif动画文件

    is = context.getResources().openRawResource(R.drawable.earth);
    movie = Movie.decodeStream(is);
}

替换第一行

public MYGIFView(Context context) {

根据班级的名字...

完成这些小的更改后,它应该对我来说...

希望这个帮助


2
您在哪个Android版本上尝试过此操作?我在Android 2.2和2.3版本上尝试过,但返回的Movie对象为null。有什么错误的主意吗?
Ashwini Shahapurkar

16
请随机清理此答案。
taxeeta

2
答案是什么问题?我只是提供了一个链接和一些必要的修正,以得到它的工作
Apperside

10

在Android上显示动画GIF的方法:

  • 电影课。如上所述,这是相当多的错误。
  • WebView。使用非常简单,通常可以正常工作。但是有时它开始出现异常,并且总是在一些您没有的晦涩的设备上。另外,您不能在任何类型的列表视图中使用多个实例,因为它会影响您的内存。尽管如此,您仍可以将其视为主要方法。
  • 自定义代码将gif解码为位图,并将其显示为Drawable或ImageView。我将提到两个库:

https://github.com/koral--/android-gif-drawable-解码器以C语言实现,因此非常高效。

https://code.google.com/p/giffiledecoder-解码器是用Java实现的,因此使用起来更容易。即使有大文件,仍然相当有效。

您还会发现许多基于GifDecoder类的库。这也是基于Java的解码器,但是它通过将整个文件加载到内存中来工作,因此它仅适用于小文件。


10

我很难让动画gif在Android中工作。我只有以下两个工作:

  1. 网页浏览
  2. 离子

WebView可以正常工作并且很容易,但是问题在于它使视图加载速度变慢,并且应用程序可能在一秒钟左右就没有响应。我不喜欢那样 所以我尝试了不同的方法(不工作):

  1. 不推荐使用ImageViewEx
  2. 毕加索未加载动画gif
  3. android-gif-drawable看起来不错,但它在我的项目中引起了一些有线NDK问题。这导致我的本地NDK库停止工作,而我无法修复它

我有一些来回交流Ion; 最后,我可以正常使用了,而且速度非常快:-)

Ion.with(imgView)
  .error(R.drawable.default_image)
  .animateGif(AnimateGifMode.ANIMATE)
  .load("file:///android_asset/animated.gif");

我在android-gif-drawable中遇到了与NDK相关的问题。
RominaV 2016年

您好@RominaV,您是否在加载gif时在离子中使用了进度条,因为加载gif时我需要显示进度。
patel135

9

滑行4.6

1.加载gif

GlideApp.with(context)
            .load(R.raw.gif) // or url
            .into(imageview);

2.获取文件对象

GlideApp.with(context)
                .asGif()
                .load(R.raw.gif) //or url
                .into(new SimpleTarget<GifDrawable>() {
                    @Override
                    public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition<? super GifDrawable> transition) {

                        resource.start();
                      //resource.setLoopCount(1);
                        imageView.setImageDrawable(resource);
                    }
                });

8

Glide

Google推荐的Android图像加载程序库。

  • Glide与毕加索非常相似,但是比毕加索快得多。
  • Glide比Picasso消耗更少的内存。

滑翔机拥有什么,但毕加索却没有

将GIF动画加载到简单ImageView的功能可能是Glide最有趣的功能。是的,您无法使用毕加索做到这一点。 一些重要的链接-在此处输入图片说明

  1. https://github.com/bumptech/glide
  2. http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

Google在哪里推荐Glid?
Derzu

1
请参阅此处,Developer Android团队在其示例应用程序中使用了Glide。 developer.android.com/samples/XYZTouristAttractions/Application/...
Shoeb西迪基

1
“ Glide与Picasso非常相似,但是比Picasso快得多”,“ Glide比Picasso消耗更少的内存。” 抱歉,我对这些想法不满意,请首选此链接:medium.com/@multidots/glide-vs-picasso-930eed42b81d。顺便说一句,由于无法将内部版本升级到3.0.1(Internet连接缓慢),我现在无法测试Glide 4.0。但是我确实在显示gif时测试了Glide 3.5.2,它可以正常工作,但并不像我预期的在大img上完美(闪烁),这也是一个常见问题。请CMIW。
Nguyen Tan Dat

7

使用ImageViewEx,这是一个使使用gif像使用gif一样容易的库ImageView



我已经看过了这些库代码,应该可以使用2年左右。
NightSkyCode 2014年

1
是的,我认为这还不错,只是指出作者决定弃用它。(因此不进行维护),指出我们应该使用像Picasso这样的东西,这很奇怪,因为Picasso是图像下载器,在显示动画gif时,它比许多下载/缓存中的任何一个都对您没有帮助。工具在那里。
Martin Marconcini 2014年

6

试试看,下面的代码在进度栏中显示gif文件

loading_activity.xml(在Layout文件夹中)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff" >

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:indeterminate="true"
        android:indeterminateDrawable="@drawable/custom_loading"
        android:visibility="gone" />

</RelativeLayout>

custom_loading.xml(在可绘制文件夹中)

我在这里放了black_gif.gif(在可绘制文件夹中),你可以在这里放自己的gif

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/black_gif"
    android:pivotX="50%"
    android:pivotY="50%" />

LoadingActivity.java(位于res文件夹中)

public class LoadingActivity extends Activity {

    ProgressBar bar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        bar = (ProgressBar) findViewById(R.id.progressBar);
        bar.setVisibility(View.VISIBLE);

    }

}

我看到你旋转了gif。为什么?
2014年

如何将gif放入可绘制文件夹中?
阿普尔瓦(Apurva)2015年


5

在本文中提出的解决方案上取得了成功,该解决方案称为类GifMovieView,可以呈现一个View可以显示或添加到特定对象的类ViewGroup。查看指定文章的第2部分和第3部分中介绍的其他方法。

此方法的唯一缺点是电影上的抗锯齿效果不是很好(必须是使用“阴暗” Android Movie类的副作用)。然后,最好在动画GIF中将背景设置为纯色。


4

关于BitmapDecode示例的一些想法...基本上,它使用了来自android.graphics 的古老而又毫无特色的Movie类。在最新的API版本上,您需要关闭硬件加速,如此处所述。否则对我来说是断断续续的。

<activity
            android:hardwareAccelerated="false"
            android:name="foo.GifActivity"
            android:label="The state of computer animation 2014">
</activity>

这是仅使用GIF部分简化的BitmapDecode示例。您必须制作自己的小部件(视图)并自己绘制。不如ImageView强大。

import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.*;
import android.view.View;

public class GifActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new GifView(this));
    }

    static class GifView extends View {
        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();
            }
        }
    }
}

本教程中,可以找到另外2种方法,一种是ImageView,另一种是WebView 。ImageView方法使用来自Google Code 的Apache许可的android-gifview


1
@luboz能否请您告诉我哪种方法对Android性能有好处...我想使用动画gif作为初始屏幕加载栏。因此,请您建议哪种方法更好。我也想知道通过使用图像查看方法可以使用比例类型属性吗?
Swap-IOS-Android


2

由于默认的浏览器支持gif文件,因此必须将其放入WebView中才能正确显示。(Froyo +,如果我没记错的话)


这不是真的。并非所有浏览器都支持GIF。
RichieHH 2014年

4
希望我们不需要所有浏览器...自android 2.2起,股票浏览器就支持它,所以请不要投票给我。WebView肯定会显示GIF!
keybee

2

有两种方法可以将动画gif加载到我们的Android应用中

1)使用Glide将gif加载到ImageView

    String urlGif = "https://cdn.dribbble.com/users/263558/screenshots/1337078/dvsd.gif";
    //add Glide implementation into the build.gradle file.
    ImageView imageView = (ImageView)findViewById(R.id.imageView);
    Uri uri = Uri.parse(urlGif);
    Glide.with(getApplicationContext()).load(uri).into(imageView);

2)使用html将gif加载到 WebView

使用.gif文件的地址创建html:

<html style="margin: 0;">
<body style="margin: 0;">
<img src="https://..../myimage.gif" style="width: 100%; height: 100%" />
</body>
</html>

将此文件存储到资产目录中:

在此处输入图片说明

将此html加载到应用程序的WebView中:

    WebView webView =  (WebView)findViewById(R.id.webView);
    webView = (WebView) findViewById(R.id.webView);
    webView.loadUrl("file:///android_asset/html/webpage_gif.html");

这是这两个选项完整示例

在此处输入图片说明


2

仅适用于android API(Android Pie)28和+

使用AnimatedImageDrawable作为

// ImageView from layout
val ima : ImageView = findViewById(R.id.img_gif)
// create AnimatedDrawable 
val decodedAnimation = ImageDecoder.decodeDrawable(
        // create ImageDecoder.Source object
        ImageDecoder.createSource(resources, R.drawable.tenor))
// set the drawble as image source of ImageView
ima.setImageDrawable(decodedAnimation)
// play the animation
(decodedAnimation as? AnimatedImageDrawable)?.start()

XML代码,添加一个ImageView

<ImageView
    android:id="@+id/img_gif"
    android:background="@drawable/ic_launcher_background" <!--Default background-->
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_width="200dp"
    android:layout_height="200dp" />

AnimatedImageDrawable 是Drawable的子级,由 ImageDecoder.decodeDrawable

ImageDecoder.decodeDrawable这进一步需要由ImageDecoder.Source创建的实例ImageDecoder.createSource

ImageDecoder.createSource只能使用source作为名称,ByteBuffer,File,resourceId,URI,ContentResolver来创建源对象,并使用它来创建AnimatedImageDrawableDrawable(多态调用)

static ImageDecoder.Source  createSource(AssetManager assets, String fileName)
static ImageDecoder.Source  createSource(ByteBuffer buffer)
static ImageDecoder.Source  createSource(File file)
static ImageDecoder.Source  createSource(Resources res, int resId)
static ImageDecoder.Source  createSource(ContentResolver cr, Uri uri)

注意:您也可以Bitmap使用ImageDecoder#decodeBitmap创建。

输出:

AnimatedDrawable还支持调整大小,框架和颜色操作


1

我认为处理gif文件的更好的库就是这个:koral

使用它,我很成功,该库专用于GIF。但是,毕加索和滑行通用图像框架;所以我认为该库的开发人员完全专注于gif文件




1

在src文件夹下创建一个名为“ Utils”的程序包,并创建一个名为“ GifImageView”的类

public class GifImageView extends View {
    private InputStream mInputStream;
    private Movie mMovie;
    private int mWidth, mHeight;
    private long mStart;
    private Context mContext;
    public GifImageView(Context context) {
        super(context);
        this.mContext = context;
    }
    public GifImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public GifImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        if (attrs.getAttributeName(1).equals("background")) {
            int id = Integer.parseInt(attrs.getAttributeValue(1).substring(1));
            setGifImageResource(id);
        }
    }
    private void init() {
        setFocusable(true);
        mMovie = Movie.decodeStream(mInputStream);
        mWidth = mMovie.width();
        mHeight = mMovie.height();
        requestLayout();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mWidth, mHeight);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        long now = SystemClock.uptimeMillis();
        if (mStart == 0) {
            mStart = now;
        }
        if (mMovie != null) {
            int duration = mMovie.duration();
            if (duration == 0) {
                duration = 1000;
            }
            int relTime = (int) ((now - mStart) % duration);
            mMovie.setTime(relTime);
            mMovie.draw(canvas, 0, 0);
            invalidate();
        }
    }
    public void setGifImageResource(int id) {
        mInputStream = mContext.getResources().openRawResource(id);
        init();
    }
    public void setGifImageUri(Uri uri) {
        try {
            mInputStream = mContext.getContentResolver().openInputStream(uri);
            init();
        } catch (FileNotFoundException e) {
            Log.e("GIfImageView", "File not found");
        }
    }
}

现在在MainActivity文件中定义GifImageView:src / activity / MainActivity.class

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GifImageView gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.smartphone_drib);
    }
}

现在,UI零件文件:res / layout / activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:gravity="center"
    android:background="#111E39"
    tools:context=".Activity.MainActivity">
    <com.android.animatedgif.Utils.GifImageView
        android:id="@+id/GifImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

资源代码:Android示例


如何调整图像大小,请
The Dead Guy

0

首先,Android浏览器应支持动画GIF。如果不是,那就是一个错误!看看问题追踪器。

如果要在浏览器外部显示这些动画GIF,则可能是另一回事。要执行您要的操作,将需要支持动画GIF解码的外部库。

首先要看的是Java2D或JAI(Java高级映像)API,但如果Android Dalvik支持您的App中的那些库,我会感到非常惊讶。


有些设备甚至在网络浏览器上也不会显示动画gif。作为示例,我知道带有Android 2.3.6的Galaxy mini无法显示它们。
android开发人员

0

类似于@Leonti所说的,但更深一些:

为了解决相同的问题,我要做的是打开GIMP,隐藏除第一层以外的所有层,将其导出为自己的图像,然后隐藏该层并取消隐藏下一层,依此类推,直到每个层都有单独的资源文件为止。然后,我可以将它们用作AnimationDrawable XML文件中的框架。


1
如果您没有那么多时间,则可以使用gifsicle提取帧。生成xml文件时,python或bash也非常方便。
lubosz 2014年


0

我为在应用程序中显示gif所做的事情。我扩展了ImageView,以便人们可以自由使用它的属性。它可以显示url或资产目录中的gif。该库还使扩展类从其继承和扩展以支持不同的方法来初始化gif变得容易。

https://github.com/Gavras/GIFView

github页面上有一些指南。

它也发布在Android Arsenal上:

https://android-arsenal.com/details/1/4947

使用示例:

从XML:

<com.whygraphics.gifview.gif.GIFView xmlns:gif_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/main_activity_gif_vie"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="center"
        gif_view:gif_src="url:http://pop.h-cdn.co/assets/16/33/480x264/gallery-1471381857-gif-season-2.gif" />

在活动中:

    GIFView mGifView = (GIFView) findViewById(R.id.main_activity_gif_vie);

    mGifView.setOnSettingGifListener(new GIFView.OnSettingGifListener() {
                @Override
                public void onSuccess(GIFView view, Exception e) {
                    Toast.makeText(MainActivity.this, "onSuccess()", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(GIFView view, Exception e) {

        }
});

以编程方式设置gif:

mGifView.setGifResource("asset:gif1");

0

最简单的方法-可以考虑以下代码

我们可以利用Imageview setImageResource,同样参考下面的代码。

如果您有多个gif分割图像,则以下代码可用于显示类似gif的图像。只需通过在线工具将gif分割成单独的png,然后将图像放入可绘制对象中,如下所示

image_1.png,image_2.png等

让处理程序动态更改图像。

int imagePosition = 1;
    Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            public void run() {
                updateImage();
            }
        };




    public void updateImage() {

                appInstance.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        int resId = getResources().getIdentifier("image_" + imagePosition, "drawable", appInstance.getPackageName());
                        gifImageViewDummy.setImageResource(resId);
                        imagePosition++;
    //Consider you have 30 image for the anim
                        if (imagePosition == 30) {
//this make animation play only once
                            handler.removeCallbacks(runnable);

                        } else {
    //You can define your own time based on the animation
                            handler.postDelayed(runnable, 50);
                        }

//to make animation to continue use below code and remove above if else
// if (imagePosition == 30)
//imagePosition = 1;
// handler.postDelayed(runnable, 50);
// 
                    }
                });
              }

0

直接从URL到应用布局显示动画GIF的简单方法是使用WebView类。

步骤1: 在布局XML中

<WebView
android:id="@+id/webView"
android:layout_width="50dp"
android:layout_height="50dp"
/>

步骤2:在您的活动中

WebView wb;
wb = (WebView) findViewById(R.id.webView);
wb.loadUrl("https://.......);

步骤3:在您的Manifest.XML中,获得Internet权限

<uses-permission android:name="android.permission.INTERNET" />

步骤4:如果您想使GIF背景透明,并使GIF适合您的布局

wb.setBackgroundColor(Color.TRANSPARENT);
wb.getSettings().setLoadWithOverviewMode(true);
wb.getSettings().setUseWideViewPort(true);


感谢您的解决方法,但由于内存,CPU使用率和电池寿命的影响,许多开发人员可能不希望使用非本机渲染
ruX


-8
public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Bitmap mBitmap;
    private Bitmap mBitmap2;
    private Bitmap mBitmap3;
    private Bitmap mBitmap4;
    private Drawable mDrawable;

    private Movie mMovie;
    private long mMovieStart;

    // Set to false to use decodeByteArray
    private static final boolean DECODE_STREAM = true;

    private static byte[] streamToBytes(InputStream is) {
      ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
      byte[] buffer = new byte[1024];
      int len;
      try {
        while ((len = is.read(buffer)) >= 0) {
          os.write(buffer, 0, len);
        }
      } catch (java.io.IOException e) {
      }
      return os.toByteArray();
    }

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      java.io.InputStream is;
      is = context.getResources().openRawResource(R.drawable.icon);

      BitmapFactory.Options opts = new BitmapFactory.Options();
      Bitmap bm;

      opts.inJustDecodeBounds = true;
      bm = BitmapFactory.decodeStream(is, null, opts);

      // now opts.outWidth and opts.outHeight are the dimension of the
      // bitmap, even though bm is null

      opts.inJustDecodeBounds = false; // this will request the bm
      opts.inSampleSize = 4; // scaled down by 4
      bm = BitmapFactory.decodeStream(is, null, opts);

      mBitmap = bm;

      // decode an image with transparency
      is = context.getResources().openRawResource(R.drawable.icon);
      mBitmap2 = BitmapFactory.decodeStream(is);

      // create a deep copy of it using getPixels() into different configs
      int w = mBitmap2.getWidth();
      int h = mBitmap2.getHeight();
      int[] pixels = new int[w * h];
      mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
      mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_8888);
      mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_4444);

      mDrawable = context.getResources().getDrawable(R.drawable.icon);
      mDrawable.setBounds(150, 20, 300, 100);

      is = context.getResources().openRawResource(R.drawable.animated_gif);

      if (DECODE_STREAM) {
        mMovie = Movie.decodeStream(is);
      } else {
        byte[] array = streamToBytes(is);
        mMovie = Movie.decodeByteArray(array, 0, array.length);
      }
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(0xFFCCCCCC);

      Paint p = new Paint();
      p.setAntiAlias(true);

      canvas.drawBitmap(mBitmap, 10, 10, null);
      canvas.drawBitmap(mBitmap2, 10, 170, null);
      canvas.drawBitmap(mBitmap3, 110, 170, null);
      canvas.drawBitmap(mBitmap4, 210, 170, null);

      mDrawable.draw(canvas);

      long now = android.os.SystemClock.uptimeMillis();
      if (mMovieStart == 0) { // first time
        mMovieStart = now;
      }
      if (mMovie != null) {
        int dur = mMovie.duration();
        if (dur == 0) {
          dur = 1000;
        }
        int relTime = (int) ((now - mMovieStart) % dur);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
            - mMovie.height());
        invalidate();
      }
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.