Android 如何在安卓中播放 GIF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20416383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:50:11  来源:igfitidea点击:

How to play GIF in android

androidandroid-animation

提问by Chethan Shetty

Hello stackoverflowI'm trying to develop an android application to play my own GIF, here is the code snippet

您好,stackoverflow我正在尝试开发一个 android 应用程序来播放我自己的应用程序GIF,这是代码片段

MainActivity.java

主活动.java

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}
}

AnimationView.java

动画视图.java

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;

public class AnimationView extends View {
private Movie mMovie;
private long mMovieStart;
private static final boolean DECODE_STREAM = true;

private int mDrawLeftPos;
private int mHeight, mWidth;

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 AnimationView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setFocusable(true);
    java.io.InputStream is;
    is = context.getResources().openRawResource(R.drawable.scanning);
    if (DECODE_STREAM) {
        mMovie = Movie.decodeStream(is);
    } else {
        byte[] array = streamToBytes(is);
        mMovie = Movie.decodeByteArray(array, 0, array.length);
    }
}

@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
{   
    int p_top = this.getPaddingTop(), p_bottom = this.getPaddingBottom();

    mWidth = mMovie.width();
    mHeight = mMovie.height();
    // Calculate new desired height
    final int desiredHSpec = MeasureSpec.makeMeasureSpec( mHeight + p_top + p_bottom , MeasureSpec.EXACTLY );

    setMeasuredDimension( widthMeasureSpec, desiredHSpec );
    super.onMeasure( widthMeasureSpec, desiredHSpec );

    // Update the draw left position
    mDrawLeftPos = Math.max( ( this.getWidth() - mWidth ) / 2, 0) ;
}

@Override
public void onDraw(Canvas 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 = 3000;
        }
        int relTime = (int) ((now - mMovieStart) % dur);
        // Log.d("", "real time :: " +relTime);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, mDrawLeftPos, this.getPaddingTop());
        invalidate();
    }
}
}

main.xml

主文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >

<com.example.androidgifwork.AnimationView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true" />
</LinearLayout>

Manifest.xml

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidgifwork"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name="com.example.androidgifwork.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

When I run the above code snippet GIFis not at all running, but when I remove android:targetSdkVersion="19"GIFrunning, please help me to solve this riddle.

当我运行上面的代码片段时GIF根本没有运行,但是当我删除android:targetSdkVersion="19"GIF运行时,请帮我解决这个谜语。

Thanks

谢谢

回答by Chethan Shetty

2017 UPDATED ANSWER

To play GIF in android use Glidelibrary to load any image or GIF.

2017 年更新的答案

要在 android 中播放 GIF,请使用Glide库加载任何图像或 GIF。

Glide.with(context)
.load(YOUR_GIF)
.into(YOUR_IMAGE_VIEW);

Use Glideto load normal images, images from server or even to load GIF as well. Also have a look at Picassoandroid image loading library which is similar to Glidebut as of now(16 Apr 2017) Picasso doesn't support GIFloading in android yet.

使用Glide加载普通图像、来自服务器的图像甚至加载 GIF。还可以查看类似于Glide 的Picassoandroid 图像加载库,但截至目前(2017 年 4 月 16 日)毕加索尚不支持在 android 中加载GIF



######################################################################

############################################### ####################

OLD ANSWER

For all Those who want to play GIF in your app please find the code belowPlayGifView.java

旧答案

对于所有想在您的应用程序中播放 GIF 的人,请在PlayGifView.java下面找到代码

 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Movie;
 import android.os.Build;
 import android.util.AttributeSet;
 import android.view.View;

 public class PlayGifView extends View{

     private static final int DEFAULT_MOVIEW_DURATION = 1000;

     private int mMovieResourceId;
     private Movie mMovie;

     private long mMovieStart = 0;
     private int mCurrentAnimationTime = 0;

     @SuppressLint("NewApi")
     public PlayGifView(Context context, AttributeSet attrs) {
         super(context, attrs);

        /**
         * Starting from HONEYCOMB have to turn off HardWare acceleration to draw
         * Movie on Canvas.
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
    }

     public void setImageResource(int mvId){
         this.mMovieResourceId = mvId;
    mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
    requestLayout();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(mMovie != null){
        setMeasuredDimension(mMovie.width(), mMovie.height());
    }else{
        setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
    }
}

@Override
protected void onDraw(Canvas canvas) {
    if (mMovie != null){
        updateAnimtionTime();
        drawGif(canvas);
        invalidate();
    }else{
        drawGif(canvas);
    }
}

private void updateAnimtionTime() {
    long now = android.os.SystemClock.uptimeMillis();

    if (mMovieStart == 0) {
        mMovieStart = now;
    }
    int dur = mMovie.duration();
    if (dur == 0) {
        dur = DEFAULT_MOVIEW_DURATION;
    }
    mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
}

private void drawGif(Canvas canvas) {
    mMovie.setTime(mCurrentAnimationTime);
    mMovie.draw(canvas, 0, 0);
    canvas.restore();
}

}

In your activity class use the following code to play GIF

在您的活动类中,使用以下代码播放 GIF

PlayGifView pGif = (PlayGifView) findViewById(R.id.viewGif);
pGif.setImageResource(<Your GIF file name Eg: R.drawable.infinity_gif>);

XML layout

XML 布局

<yourPacckageName.PlayGifView
            android:id="@+id/viewGif"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />

回答by Hitesh Sahu

Use Glideto load any gif from your project's rawfolder or external URL into ImageView, ImageButtonsor similar [Glide targets][2]

使用Glide将项目raw文件夹或外部 URL 中的任何 gif 加载到ImageView, ImageButtons或类似的[Glide targets][2]

Glide.with(getActivity()).load(R.raw.alarm).asGif().into(btnAlert);

回答by Sushil

If you can use a WebView, GIFs will play directly over it. But I am not sure, in your case whether you want to put it in a Webview or not.

如果您可以使用 WebView,则 GIF 将直接在其上播放。但我不确定,在你的情况下,你是否想把它放在 Webview 中。

回答by insomniac

Android provides the class android.graphics.Movie. This class is capable of decoding and playing InputStreams. So for this approach, we create a class GifMovieView and let it inherit from View a detailed tutorial is given at http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/

Android 提供了类 android.graphics.Movie。此类能够解码和播放 InputStreams。因此,对于这种方法,我们创建了一个类 GifMovieView 并让它从 View 继承,详细教程在http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-在-android-part-1/

回答by Keshav Gera

Source Codehttps://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU

源代码https://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU

** android:hardwareAccelerated="false" in Manifest File**

** android:hardwareAccelerated="false" 在清单文件中**

package com.keshav.gifimageexampleworking;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity
{
    private GifImageView gifImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gifImageView = (GifImageView) findViewById(R.id.GifImageView);

        gifImageView.setGifImageResource(R.drawable.success1);

    }

 @Override
 protected void onResume() 
 {
    super.onResume();

    //refresh long-time task in background thread
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                //dummy delay for 2 second
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //update ui on UI thread
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    gifImageView.setGifImageResource(R.drawable.success);
                }
            });

        }
    }).start();
   }
}


package com.keshav.gifimageexampleworking;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.net.Uri;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.io.FileNotFoundException;
import java.io.InputStream;


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, 10, 10);
            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");
        }
    }
}

回答by SafiZidan

add this to your dependencies (build.gradle)

将此添加到您的依赖项(build.gradle)

 allprojects {
    repositories {
        mavenCentral()
    }
}
dependencies {
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
    implementation 'com.google.android.gms:play-services-ads:18.1.1'

}

and use this in xml to show your gif

并在 xml 中使用它来显示您的 gif

 <pl.droidsonroids.gif.GifTextView
                    android:id="@+id/gifTextView2"
                    android:layout_width="230dp"
                    android:layout_height="200dp"
                    android:layout_weight="1"
                    android:background="@drawable/dev_option_gif"
                    />

回答by Oush

For devices running API 29(Pie) & above you can use AnimatedImageDrawableto play GIF(s) and WebP animated images.

对于运行 API 29(Pie) 及以上版本的设备,您可以使用AnimatedImageDrawable来播放 GIF(s) 和 WebP 动画图像。

Here's a sample:

这是一个示例:

ImageView imgGif = findViewById(R.id.imgGif);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        try {
            drawable = ImageDecoder.decodeDrawable(ImageDecoder.createSource(getResources(), R.drawable.giphy));
            imgGif.setImageDrawable(drawable);

            if (drawable instanceof AnimatedImageDrawable) {
                ((AnimatedImageDrawable) drawable).start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Using this provides more control & features you can use on the image such as:

使用它可以提供更多可以在图像上使用的控制和功能,例如:

  • Checking whether the gif is running
  • Starting & stopping the playback.
  • Applying color filters
  • Changing image shape

    and much more

  • 检查gif是否正在运行
  • 开始和停止播放。
  • 应用颜色过滤器
  • 改变图像形状

    还有更多