Hello stackoverflow
I'm trying to develop an android application to play my own GIF
, here is the code snippet
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>
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.
Thanks
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" />