3

In a nutshell, I have an Activity A, which applied setContentView(R.id.layout_a), and A will run for 5 seconds.

I tried to define a custom View class and using Movie class to load the gif, then attach the custom view to layout_a but it displays just blank.

The WebView method

I tried WebView, it can display the gif well, but the gif can animate only the first time I launch this activity. It will just show the last frame when later activity A is launched.

I tried WebView.reload() but no sweet.

Here's my code when trying to apply the WebView:

public class activityA extends Activity {

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    setContentView(R.layout.activity_a);

    WebView splashFrame = (WebView)findViewById(R.id.splashFrame);

    splashFrame.setBackgroundColor(Color.TRANSPARENT);
    splashFrame.loadDataWithBaseURL("file:///android_res/drawable/", "<img align='middle' src='face_morph_gif.gif' width='100%' />", "text/html", "utf-8", null);
    splashFrame.reload();

    Handler handler = new Handler();

    // run a thread after 3 seconds to start the home screen
    handler.postDelayed(new Runnable() {

        @Override
        public void run() {

            // make sure we close the splash screen so the user won't come back when it presses back key

            finish();
            // start the home screen

            Intent intent = new Intent(activityA.this, activityB.class);
            SplashScreenActivity.this.startActivity(intent);
        }

    }, 5000); 

  }      
}

So here comes my Question 1: How to make this gif play from the beginning when I launch activity A? I noticed that when I open this gif using Safari/Chrome, it will play just once till I manually refresh the browser.

The Custom View method

This is the first way I was looking into but I couldn't get work even once.

Activity A code:

public class activityA extends Activity {

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    setContentView(R.layout.activity_a);
    Handler handler = new Handler();

    // run a thread after 3 seconds to start the home screen
    handler.postDelayed(new Runnable() {

        @Override
        public void run() {

            // make sure we close the splash screen so the user won't come back when it presses back key

            finish();
            // start the home screen

            Intent intent = new Intent(activityA.this, activityB.class);
            SplashScreenActivity.this.startActivity(intent);
        }

    }, 5000); 

  }      
}

The Custome View:

public class GifView extends View {

public Movie mMovie;
public long mMovieStart;

public GifView(Context context) {
    super(context);
    setFocusable(true);
    InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
    mMovie = Movie.decodeStream(is);
}

public GifView(Context context, AttributeSet attr) {
    super(context, attr);
    setFocusable(true);
    InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
    mMovie = Movie.decodeStream(is);
}

public GifView(Context context, AttributeSet attr, int defStyle) {
    super(context, attr, defStyle);
    setFocusable(true);
    InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
    mMovie = Movie.decodeStream(is);

}

@Override
protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
//       canvas.drawColor(Color.TRANSPARENT);
   final long now = SystemClock.uptimeMillis();
   if (mMovieStart == 0) {
      mMovieStart = now;
   }
   if (mMovie != null) {
       int dur = mMovie.duration();
//         Log.d("gif Canvas", "duration: " + mMovie.duration());
       if (dur == 0) {
           dur = 4000;
       }

       int relTime = (int)((now - mMovieStart) % dur);
       mMovie.setTime(relTime);
       mMovie.draw(canvas, 10, 10);
//         Log.d("gif Canvas", mMovie.width() + "x" + mMovie.height());
       invalidate();
   }
}

@Override
  protected void onMeasure(final int widthMeasureSpec,
     final int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
}

}

And the xml of layout_a

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/app_background"
tools:ignore="ContentDescription" >

<ImageView
    ... />

<ImageView
    ... />

<ImageView
    ... />

<ImageView
    ... />


<com.xxx.GifView 
    android:id="@+id/splashFrame"
    android:layout_width="95dp" 
    android:layout_height="156dp" 
    android:visibility="visible" />

So here comes my Question 2: Why this custom view can't display the gif? I set break points in onDraw method and I am sure the mMovie can load the gif (mMovie can return correct width and height of the gif)

I know getting gif to work on Android is a quite old topic, AFAIK there are 3 ways:

  1. Movie Class

  2. Custom View

  3. Split GIF/Use Android Animation

I can't use the third way because the gif I am using has 100 frames, and its not cheap.

I've go through all the tutorials and SO questions, but none of them can make this work.

Thank you for reading my questions.

dumbfingers
  • 7,001
  • 5
  • 54
  • 80
  • Are you looking for something like a wellcome screen for your app? – Milos Cuculovic Oct 11 '12 at 11:39
  • @Milos Exactly. But I just want to display this gif like ImageView, not fullscreen. As you can see in the xml there are several other `ImageView`s – dumbfingers Oct 11 '12 at 11:42
  • why not using the movie class for playing your gif? – Milos Cuculovic Oct 11 '12 at 11:51
  • @Milos I tried to use in my Custom View, but no luck. Is that what you mean? – dumbfingers Oct 11 '12 at 11:52
  • Sorry, after reading some topics, if you are using this on android 2.2 or later, you can use a simple webview. See: http://droid-blog.net/2011/10/17/tutorial-how-to-play-animated-gifs-in-android-part-3/ – Milos Cuculovic Oct 11 '12 at 11:58
  • with that, you can create a Webview in your layout, populate the view with the gif and it's done. – Milos Cuculovic Oct 11 '12 at 11:59
  • @Milos Yes, I have read this article. My WebView method can load the gif. But it can only play once, which means when you launch the app for a second time, the gif just show you the last frame without any animation. – dumbfingers Oct 11 '12 at 12:00
  • For that, you have to fix two things: 1. Be sure that your gif is made to be animated repeately. For that, you have to edit the GIF file to enable endless animation loop if not done. 2. Be sure to not use cache for your webview. For that, set the cache to false when creating the webView – Milos Cuculovic Oct 11 '12 at 12:06
  • @Milos thx. I cleared cache and it can play from start each time I launch the activity, no need to create a loop gif. Please post it as an answer – dumbfingers Oct 11 '12 at 12:46
  • Done, enjoy.... And a +1 for you. – Milos Cuculovic Oct 11 '12 at 12:49

2 Answers2

1

In order to play a GIF animation in your android phone, I suggest you to use a WebView (only for Android 2.2 an higher).

A good tutorial can be found here: http://droid-blog.net/2011/10/17/tutorial-how-to-play-animated-gifs-in-android-part-3/

Be careful to clear the cache in order to play the animated GIF each time you open your WebView. Use webView.clearCache(false);

Enjoy.

Tim Pierce
  • 5,514
  • 1
  • 15
  • 31
Milos Cuculovic
  • 19,631
  • 51
  • 159
  • 265
  • Here is the answer to Question1 "Be careful to clear the cache in order to play the animated GIF each time you open your WebView." So you nedd to use `webView.clearCache(false);` This worked for me. – Roman Nazarevych Nov 06 '15 at 16:51
0

You can convert your GIFs to WebP format.

A few utilities are available online, this is one of them: http://www.zamzar.com/convert/gif-to-webp/

Assaf S.
  • 4,676
  • 2
  • 22
  • 18