web-dev-qa-db-fra.com

Comment jouer GIF dans Android

Bonjour stackoverflow J'essaie de développer une application Android pour jouer ma propre GIF, voici l'extrait de code

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>

Lorsque je lance l'extrait de code ci-dessus, GIF ne s'exécute pas du tout, mais lorsque je supprime Android:targetSdkVersion="19"GIF, aidez-moi à résoudre cette énigme. 

Merci

17
Chethan Shetty

2017 RÉPONSE MISE À JOUR

Pour jouer au format GIF sous Android, utilisez Glide library pour charger une image ou un fichier GIF.

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

Utilisez Glide pour charger des images normales, des images du serveur ou même du GIF. Consultez également la bibliothèque de chargement d’images Picasso Android similaire à Glide, mais pour le moment (16 avr. 2017) Picasso ne prend pas en charge GIF Android encore.


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

ANCIENNE RÉPONSE

Pour tous ceux qui souhaitent lire des images GIF dans votre application, veuillez trouver le code ci-dessousPlayGifView.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();
}

}

Dans votre classe d'activité, utilisez le code suivant pour lire le GIF

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

Mise en page XML

<yourPacckageName.PlayGifView
            Android:id="@+id/viewGif"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center" />
49
Chethan Shetty

Utilisez Glide pour charger tout gif du dossier raw de votre projet ou une URL externe dans ImageView, ImageButtons ou similaire [Glide targets][2].

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

Si vous pouvez utiliser une vue Web, les fichiers GIF seront lus directement dessus. Mais je ne suis pas sûr, dans votre cas, si vous voulez le mettre dans une Webview ou non.

1
Sushil

C’est vieux, je le sais, mais ici, vous pouvez prendre une WebView, créer un html qui jouera le gif et transmettra l’URL de la vue Web, cela fonctionnera à merveille.

1
Abdul Ahad

Code sourcehttps://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU

** Android: hardwareAccelerated = "false" dans le fichier manifeste **

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");
        }
    }
}
0
Keshav Gera

Android fournit la classe Android.graphics.Movie. Cette classe est capable de décoder et de jouer à InputStreams. Donc, pour cette approche, nous créons une classe GifMovieView et laissons hériter de View. Un tutoriel détaillé est présenté à http://droid-blog.net/2011/10/14/tutorial-how-to-use-animated- gifs dans Android partie 1/

0
insomniac