Как играть в GIF в android

Здравствуйте stackoverflow Я пытаюсь разработать приложение для Android, чтобы воспроизвести собственный GIF, вот фрагмент кода

MainActivity.java

public class MainActivity extends Activity {

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

AnimationView.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>

Когда я запускаю приведенный выше фрагмент кода GIF, он не работает, но когда я удаляю android:targetSdkVersion="19" GIF, запустите, пожалуйста, помогите мне решить эту загадку.

Спасибо

Ответ 1

2017 ОБНОВЛЕННЫЙ ОТВЕТ

Для воспроизведения GIF в Android используйте библиотеку Glide, чтобы загрузить любое изображение или GIF.

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

Используйте Glide для загрузки обычных изображений, изображений с сервера или даже для загрузки GIF. Также обратите внимание на библиотеку загрузки изображений Android Picasso, которая похожа на Glide, но на данный момент (16 апреля 2017 года) Picasso не поддерживает GIF загрузка в Android еще.


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

СТАРЫЙ ОТВЕТ

Для всех тех, кто хочет играть в 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();
}

}

В своем классе деятельности используйте следующий код для игры в GIF

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

XML-макет

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

Ответ 2

Используйте Glide для загрузки любого gif из вашей папки raw или внешнего URL проекта в ImageView, ImageButtons или аналогичный [Glide targets][2]

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

Ответ 3

Если вы можете использовать WebView, GIF будут воспроизводиться непосредственно над ним. Но я не уверен, в вашем случае, хотите ли вы поместить его в Webview или нет.

Ответ 4

Это старый, который я знаю, но вот он, вы можете взять WebView, создать html, который будет воспроизводить gif и передать URL-адрес в webview, он будет работать как шарм.

Ответ 5

Android предоставляет класс android.graphics.Movie. Этот класс способен декодировать и воспроизводить InputStreams. Таким образом, для этого подхода мы создаем класс GifMovieView и позволяем ему наследовать от View. Подробный учебник приведен в http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated-gifs-in-android-part-1/

Ответ 6

Исходный код  https://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU

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

Ответ 7

добавьте это в свои зависимости (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'

}

и используйте это в 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"
                    />