在Android中全屏显示GIF图片
2017-08-20 00:23
288 查看
1、自定义一个GifView
首先自定义一个GifView,用于显示Gif图片。GifView的代码参考自https://github.com/Cutta/GifView。package cc.duduhuo.gifviewdemo.view; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Movie; import android.os.Build; import android.os.SystemClock; import android.support.annotation.NonNull; import android.util.AttributeSet; import android.view.View; /** * ======================================================= * 作者:liying - liruoer2008@yeah.net * 日期:2017/8/19 20:09 * 版本:1.0 * 描述:自定义显示Gif图片的View * 备注: * ======================================================= */ public class GifView extends View { private static final int DEFAULT_MOVIE_VIEW_DURATION = 1000; private int mMovieResourceId; private Movie mMovie; private long mMovieStart; private int mCurrentAnimationTime; /** * Position for drawing animation frames in the center of the view. */ private float mLeft; private float mTop; /** * Scaling factor to fit the animation within view bounds. */ private float mScale; /** * Scaled movie frames width and height. */ private int mMeasuredMovieWidth; private int mMeasuredMovieHeight; private volatile boolean mPaused; private boolean mVisible = true; public GifView(Context context) { this(context, null); } public GifView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GifView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { /* * Starting from HONEYCOMB(Api Level:11) have to turn off HW acceleration to draw * Movie on Canvas. */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } public void setGifResource(int movieResourceId) { this.mMovieResourceId = movieResourceId; mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId)); requestLayout(); } public int getGifResource() { return this.mMovieResourceId; } public void play() { if (this.mPaused) { this.mPaused = false; /* * Calculate new movie start time, so that it resumes from the same * frame. */ mMovieStart = SystemClock.uptimeMillis() - mCurrentAnimationTime; invalidate(); } } public void pause() { if (!this.mPaused) { this.mPaused = true; invalidate(); } } public boolean isPaused() { return this.mPaused; } public boolean isPlaying() { return !this.mPaused; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMovie != null) { int movieWidth = mMovie.width(); int movieHeight = mMovie.height(); /* * Calculate horizontal scaling */ float scaleH = 1f; int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec); if (measureModeWidth != MeasureSpec.UNSPECIFIED) { int maximumWidth = MeasureSpec.getSize(widthMeasureSpec); if (movieWidth > maximumWidth) { scaleH = (float) movieWidth / (float) maximumWidth; } } /* * calculate vertical scaling */ float scaleW = 1f; int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec); if (measureModeHeight != MeasureSpec.UNSPECIFIED) { int maximumHeight = MeasureSpec.getSize(heightMeasureSpec); if (movieHeight > maximumHeight) { scaleW = (float) movieHeight / (float) maximumHeight; } } /* * calculate overall scale */ mScale = 1f / Math.max(scaleH, scaleW); mMeasuredMovieWidth = (int) (movieWidth * mScale); mMeasuredMovieHeight = (int) (movieHeight * mScale); setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight); } else { /* * No movie set, just set minimum available size. */ setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight()); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); /* Calculate mLeft / mTop for drawing in center */ 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); } } } /** * Invalidates view only if it is mVisible. * <br> * {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher. */ @SuppressLint("NewApi") private void invalidateView() { if (mVisible) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { postInvalidateOnAnimation(); } else { invalidate(); } } } /** * Calculate current animation time */ private void updateAnimationTime() { long now = android.os.SystemClock.uptimeMillis(); if (mMovieStart == 0) { mMovieStart = now; } int dur = mMovie.duration(); if (dur == 0) { dur = DEFAULT_MOVIE_VIEW_DURATION; } mCurrentAnimationTime = (int) ((now - mMovieStart) % dur); } /** * Draw current GIF frame */ private void drawMovieFrame(Canvas canvas) { mMovie.setTime(mCurrentAnimationTime); canvas.save(); canvas.scale(mScale, mScale); mMovie.draw(canvas, mLeft / mScale, mTop / mScale); canvas.restore(); } @SuppressLint("NewApi") @Override public void onScreenStateChanged(int screenState) { super.onScreenStateChanged(screenState); mVisible = screenState == SCREEN_STATE_ON; invalidateView(); } /** * get gif width * * @return width */ public int getGifWidth() { return mMovie.width(); } /** * get gif height * * @return height */ public int getGifHeight() { return mMovie.height(); } @SuppressLint("NewApi") @Override protected void onVisibilityChanged(@NonNull 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(); } }
重要的是要添加
getGifWidth()和
getGifHeight()两个方法,用于获取Gif图片的宽高。
(注:获取Gif图片的宽和高可以简单等价于获取对应Movie对象的宽和高。)
2、在布局文件中使用GifView
自定义的View可以在布局文件中直接使用。<cc.duduhuo.gifviewdemo.view.GifView android:id="@+id/gifView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/>
3、缩放Gif图片,使之全屏显示
首先需要调用GifView的
setGifResource(int)方法设置要显示的Gif图片。
GifView gifView = (GifView) findViewById(R.id.gifView); gifView.setGifResource(R.drawable.gif1); // 设置显示的Gif图片
其次,调用
GifView的
getGifWidth()方法和
getGifHeight()方法得到Gif图片的宽和高。再获取到当前屏幕的宽和高,分别计算屏幕和Gif图片的宽度和高度比例。为了使图片的宽高比例保持不变,选择缩放比例较小的一边进行缩放。
int width = gifView.getGifWidth(); int height = gifView.getGifHeight(); int screenWidth = getScreenSize().width(); int screenHeight = getScreenSize().height(); if (width > 0 && height > 0) { float wScale = (float) screenWidth / width; float hScale = (float) screenHeight / height; if (wScale < 1 || hScale < 1) { // 如果图片的宽或高大于屏幕的宽或高,则图片会自动缩小至全屏 } else if (wScale <= hScale) { // 宽度全屏 gifView.setScaleX(wScale); gifView.setScaleY(wScale); } else { // 高度全屏 gifView.setScaleX(hScale); gifView.setScaleY(hScale); } }
getScreenSize()方法用于获取屏幕的宽度和高度。
/** * 得到屏幕的尺寸 * * @return 包含屏幕尺寸的Rect对象 */ private Rect getScreenSize() { Rect localRect = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect); return localRect; }
4、效果演示
宽度全屏 | 高度全屏 |
---|---|
5、代码下载
Demo代码下载:http://download.csdn.net/download/u012939909/9941754相关文章推荐
- Android显示gif格式图片
- android中使用imageview显示Gif图片
- Android—基于GifView显示gif动态图片
- Android gif图片显示
- Android三步显示gif动态图片
- Android设置图片为手机壁纸,并且全屏显示。
- android显示gif图片(上)
- Android 2.3 Gallery3D添加gif支持——图片显示(二)
- Android显示gif格式图片
- Android中显示gif动态图片
- [Android开发]Gif图片下载和显示
- android中自定义view显示gif格式图片
- Android中Gif图片的显示
- Android 显示GIF图片实例详解
- android 显示gif图片
- android使用movie显示gif图片的自定义view
- Android中显示gif动态图片
- Android显示GIF图片实例代码
- Android中轻松显示Gif图片
- Android Gif图片显示(GifView)