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
How to play GIF in android
提问by Chethan Shetty
Hello stackoverflow
I'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 GIF
is not at all running, but when I remove android:targetSdkVersion="19"
GIF
running, 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
回答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是否正在运行
- 开始和停止播放。
- 应用颜色过滤器
改变图像形状
还有更多