Hello stackoverflow
I\'m trying to develop an android application to play my own GIF
, here is the code snippet
MainActivity.java
Use Glide to load any gif from your project's raw
folder or external URL into ImageView, ImageButtons
or similar [Glide targets][2]
Glide.with(getActivity()).load(R.raw.alarm).asGif().into(btnAlert);
Source Code https://drive.google.com/open?id=0BzBKpZ4nzNzUZy1BVlZSbExvYUU
** android:hardwareAccelerated="false" in Manifest File**
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");
}
}
}
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/
2017 UPDATED ANSWER
To play GIF in android use Glide library to load any image or GIF.
Glide.with(context)
.load(YOUR_GIF)
.into(YOUR_IMAGE_VIEW);
Use Glide to load normal images, images from server or even to load GIF as well. Also have a look at Picasso android image loading library which is similar to Glide but as of now(16 Apr 2017) Picasso doesn't support GIF loading in android yet.
######################################################################
OLD ANSWER
For all Those who want to play GIF in your app please find the code below
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
PlayGifView pGif = (PlayGifView) findViewById(R.id.viewGif);
pGif.setImageResource(<Your GIF file name Eg: R.drawable.infinity_gif>);
XML layout
<yourPacckageName.PlayGifView
android:id="@+id/viewGif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
You can also use Coil library, which gives you a bit less control over Gif images than Glide does. But still gives simple implementation if you just want to load the GIF once and show. Probably, if you want to repeat that you need to trigger the drawable again or just call the load function once again. Anyway even if calling load again the resources should be cached under the hood(something to be investigated, not 100% sure). Everything you need is adding dependency:
implementation "io.coil-kt:coil-gif:1.0.0"
And specifying your decoding mechanism:
val imageLoader = ImageLoader.Builder(context)
.componentRegistry {
if (SDK_INT >= 28) {
add(ImageDecoderDecoder())
} else {
add(GifDecoder())
}
}
.build()
That's all go-ahead and load images/gifs directly in your image views:
app_logo.load("needed_gif_url")
Don't forget to pass the needed image loader to each request where you need your decoder to be used, as for GIFs. Or just make your custom imageLoader as default for each request:
Coil.setImageLoader(imageLoader)
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.