Android 显示Gif 动态图片

项目(showgif)已推到GitHub,查看文末的链接即可下载。

显示如下一张Gif动态图片:

看一下在demo中的效果:

按钮用来暂停和继续。看一下代码逻辑实现:

package com.zms.showgif;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class Main extends ActionBarActivity {
    private GifImageView gifImageView;
    private Button btnPause;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        gifImageView = (GifImageView) findViewById(R.id.imgGif);
        gifImageView.setMovieResource(R.raw.showme);
        btnPause = (Button) findViewById(R.id.btnPause);
        btnPause.setOnClickListener(new OnClickListenerImp());
    }

    private class OnClickListenerImp implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            if (v == btnPause) {
                if (gifImageView.isPaused()) {
                    gifImageView.setPaused(false);
                    btnPause.setText("Pause");
                } else {
                    gifImageView.setPaused(true);
                    btnPause.setText("Play");
                }
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

核心的自定义View:

package com.zms.showgif;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by AlexZhou on 2015/1/29.
 * 16:42
 */
public class GifImageView extends View {

    // 默认为1秒
    private static final int DEFAULT_MOVIE_DURATION = 1000;
    private int mMovieResourceId;
    private Movie mMovie;
    private long mMovieStart;
    private int mCurrentAnimationTime = 0;
    private float mLeft;
    private float mTop;
    private float mScale;
    private int mMeasuredMovieWidth;
    private int mMeasuredMovieHeight;
    private boolean mVisible = true;
    private volatile boolean mPaused = false;

    public GifImageView(Context context) {
        this(context, null);
    }

    public GifImageView(Context context, AttributeSet attrs) {
        this(context, attrs, R.styleable.Gif_style);
    }

    public GifImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setViewAttributes(context, attrs, defStyle);
    }

    private void setViewAttributes(Context context, AttributeSet attrs,
                                   int defStyle) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        // 从描述文件中读出gif的值,创建出Movie实例
        final TypedArray array = context.obtainStyledAttributes(attrs,
                R.styleable.Gif, defStyle, -1);
        mMovieResourceId = array.getResourceId(R.styleable.Gif_resource, -1);
        mPaused = array.getBoolean(R.styleable.Gif_paused, false);
        array.recycle();
        if (mMovieResourceId != -1) {
            mMovie = Movie.decodeStream(getResources().openRawResource(
                    mMovieResourceId));
        }
    }

    public int setMovieResource(int movieResId) {
        this.mMovieResourceId = movieResId;
        mMovie = Movie.decodeStream(getResources().openRawResource(
                mMovieResourceId));
        requestLayout();
        return movieResId;
    }

    public void setMovie(Movie movie) {
        this.mMovie = movie;
        requestLayout();
    }

    public Movie getMovie() {
        return mMovie;
    }

    public void setMovieTime(int time) {
        mCurrentAnimationTime = time;
        invalidate();
    }

    /**
     * 设置暂停
     *
     * @param paused
     */
    public void setPaused(boolean paused) {
        this.mPaused = paused;
        if (!paused) {
            mMovieStart = android.os.SystemClock.uptimeMillis()
                    - mCurrentAnimationTime;
        }
        invalidate();
    }

    /**
     * 判断gif图是否停止了
     *
     * @return
     */
    public boolean isPaused() {
        return this.mPaused;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mMovie != null) {
            int movieWidth = mMovie.width();
            int movieHeight = mMovie.height();
            int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
            float scaleW = (float) movieWidth / (float) maximumWidth;
            mScale = 1f / scaleW;
            mMeasuredMovieWidth = maximumWidth;
            mMeasuredMovieHeight = (int) (movieHeight * mScale);
            setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);
        } else {
            setMeasuredDimension(getSuggestedMinimumWidth(),
                    getSuggestedMinimumHeight());
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;
        mTop = (getHeight() - mMeasuredMovieHeight) / 2f;
        mVisible = getVisibility() == View.VISIBLE;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mMovie != null) {
            if (!mPaused) {
                updateAnimationTime();
                drawMovieFrame(canvas);
                invalidateView();
            } else {
                drawMovieFrame(canvas);
            }
        }
    }

    private void invalidateView() {
        if (mVisible) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                postInvalidateOnAnimation();
            } else {
                invalidate();
            }
        }
    }

    private void updateAnimationTime() {
        long now = android.os.SystemClock.uptimeMillis();
        // 如果第一帧,记录起始时间
        if (mMovieStart == 0) {
            mMovieStart = now;
        }
        // 取出动画的时长
        int dur = mMovie.duration();
        if (dur == 0) {
            dur = DEFAULT_MOVIE_DURATION;
        }
        // 算出需要显示第几帧
        mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
    }

    private void drawMovieFrame(Canvas canvas) {
        // 设置要显示的帧,绘制即可
        mMovie.setTime(mCurrentAnimationTime);
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        canvas.scale(mScale, mScale);
        mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
        canvas.restore();
    }

    @Override
    public void onScreenStateChanged(int screenState) {
        super.onScreenStateChanged(screenState);
        mVisible = screenState == SCREEN_STATE_ON;
        invalidateView();
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        mVisible = visibility == View.VISIBLE;
        invalidateView();
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        mVisible = visibility == View.VISIBLE;
        invalidateView();
    }
}

转载请注明出处:周木水的CSDN博客 http://blog.csdn.net/zhoumushui

我的GitHub:周木水的GitHub https://github.com/zhoumushui

时间: 2024-11-12 12:00:25

Android 显示Gif 动态图片的相关文章

Android—基于GifView显示gif动态图片

android中显示gif动态图片用到了开源框架GifView 1.拷GifView.jar到自己的项目中. 2.将自己的gif图片拷贝到drawable文件夹 3.在xml文件中设置基本属性: <com.ant.liao.GifView android:id="@+id/gifView" android:layout_centerInParent="true" android:layout_width="wrap_content" and

Android三步显示gif动态图片

今天给大家带来一个显示gif动态图片的类库,使用方法很简单,只需三步. 1.把GifView.jar加入你的项目. 2.在布局xml中这样写: <com.ant.liao.GifView android:id="@+id/gif1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:paddingTop="4px&quo

32Spannable的使用(Android显示html带图片 (表情开发))

Android中显示html文件要用Html.fromHtml(...)处理过的返回值,返回值可以成为setText()的参数.只显示带文本的html可以用下面的方法处理html文件. public static Spanned fromHtml (String source) 显示带图片的html要用下面的方法处理html文件. public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.T

android显示网络gif图片

这功能源自负责app中要加一个显示gif广告图功能. android自带控件不支持gif图片,网上很多通过扩展ImageView或View来实现支持gif图片,但在android4.0后,需要关闭硬件加速功能才能使用,而且也容易出现内存溢出问题. 网上找了两个开源包来实现显示Gif图 android-gif-drawable 支持gif显示的view控件 项目地址:https://github.com/koral--/android-gif-drawable 用jni实现的,编译生成so库后直接

Android显示等宽图片的问题

安卓开发常遇到一个问题,就是在listView里面,在不知道图片宽高的前提下,另图片布满屏幕(图片宽度等于屏幕宽度,高度自适应).在listView中,只是设置scaleType,imageView.setBackground()是一定程度上导致图片拉伸失真,setImageDrawable()则不能满屏.参考网上的几种方案,自己总结了一个比较简单可用的: imageView布局: 1 <ImageView 2 android:id="@+id/imgIco" 3 android

android 显示目录下图片

知识点 1. 网格视图 2. 读取文件 MainAcitvity package com.test.gridview; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.GridView; import android.widget.

Android显示GIF图片

<span style="font-family: KaiTi_GB2312; background-color: rgb(255, 255, 255);">今天我们研究一下如何在Android手机上显示GIF动态图片.</span> 首先需要在src目录下新建一个自定义的View,代码如下: import android.content.Context; import android.graphics.Canvas; import android.graphi

Android之动态图片

在Android中,比起静态图片来动态图片会更加生动更加酷炫,因为这种视觉效果,你应该会发现我们手机中大多数应用软件的导航页面也都是采用动态图片来展示.动态图片的格式有gif.png格式等等. 我们就来看看动态图片,我们可以先自定义SurfaceView视图,然后在MainActivity中添加显示方法就行了. MainActivity: package com.cdp.dongtaitupian;; import android.app.Activity; import android.os.

Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示

Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过Paint和onDraw()进行圆形图片显示. 效果图: 代码: 1 activity_image.xml 2 <?xml version="1.0" encoding="utf-8"?> 3 <LinearLayoutxmlns:android=&q