android播放GIF

来源:互联网 发布:听电子书的软件 编辑:程序博客网 时间:2024/05/16 01:32
本人菜鸟,今天看到国外写的android播放gif图片的例子。。与大家分享!也比较简单。类也少就一个!
但是如果gif图片过大(我试过8M),图片边缘就会出现锯齿。如果gif小,那就完全没影响,加载速度也算快!
录制的gif图不太好。


  1. import android.annotation.SuppressLint;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Canvas;
  5. import android.graphics.Movie;
  6. import android.os.Build;
  7. import android.util.AttributeSet;
  8. import android.view.View;

  9. /**
  10. * This is a View class that wraps Android {[url=home.php?mod=space&uid=91636]@link[/url] Movie} object and displays it.
  11. * You can set GIF as a Movie object or as a resource id from XML or by calling
  12. * {@link #setMovie(Movie)} or {@link #setMovieResource(int)}.
  13. * <p>
  14. * You can pause and resume GIF animation by calling {@link #setPaused(boolean)}.
  15. * <p>
  16. * The animation is drawn in the center inside of the measured view bounds.

  17. * @author Sergey Bakhtiarov
  18. */

  19. public class GifMovieView extends View {

  20.         private static final int DEFAULT_MOVIEW_DURATION = 1000;

  21.         private int mMovieResourceId;
  22.         private Movie mMovie;

  23.         private long mMovieStart;
  24.         private int mCurrentAnimationTime = 0;
  25.         
  26.         /**
  27.          * Position for drawing animation frames in the center of the view.
  28.          */
  29.         private float mLeft;
  30.         private float mTop;

  31.         /**
  32.          * Scaling factor to fit the animation within view bounds.
  33.          */
  34.         private float mScale;

  35.         /**
  36.          * Scaled movie frames width and height.
  37.          */
  38.         private int mMeasuredMovieWidth;
  39.         private int mMeasuredMovieHeight;

  40.         private volatile boolean mPaused = false;
  41.         private boolean mVisible = true;

  42.         public GifMovieView(Context context) {
  43.                 this(context, null);
  44.         }

  45.         public GifMovieView(Context context, AttributeSet attrs) {
  46.                 this(context, attrs, R.styleable.CustomTheme_gifMoviewViewStyle);
  47.         }

  48.         public GifMovieView(Context context, AttributeSet attrs, int defStyle) {
  49.                 super(context, attrs, defStyle);

  50.                 setViewAttributes(context, attrs, defStyle);
  51.         }

  52.         @SuppressLint("NewApi")
  53.         private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) {

  54.                 /**
  55.                  * Starting from HONEYCOMB have to turn off HW acceleration to draw
  56.                  * Movie on Canvas.
  57.                  */
  58.                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  59.                         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
  60.                 }

  61.                 final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifMoviewView, defStyle,
  62.                                 R.style.Widget_GifMoviewView);

  63.                 mMovieResourceId = array.getResourceId(R.styleable.GifMoviewView_gif, -1);
  64.                 mPaused = array.getBoolean(R.styleable.GifMoviewView_paused, false);

  65.                 array.recycle();

  66.                 if (mMovieResourceId != -1) {
  67.                         mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
  68.                 }
  69.         }

  70.         public void setMovieResource(int movieResId) {
  71.                 this.mMovieResourceId = movieResId;
  72.                 mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
  73.                 requestLayout();
  74.         }

  75.         public void setMovie(Movie movie) {
  76.                 this.mMovie = movie;
  77.                 requestLayout();
  78.         }

  79.         public Movie getMovie() {
  80.                 return mMovie;
  81.         }

  82.         public void setMovieTime(int time) {
  83.                 mCurrentAnimationTime = time;
  84.                 invalidate();
  85.         }

  86.         public void setPaused(boolean paused) {
  87.                 this.mPaused = paused;

  88.                 /**
  89.                  * Calculate new movie start time, so that it resumes from the same
  90.                  * frame.
  91.                  */
  92.                 if (!paused) {
  93.                         mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime;
  94.                 }

  95.                 invalidate();
  96.         }

  97.         public boolean isPaused() {
  98.                 return this.mPaused;
  99.         }

  100.         @Override
  101.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  102.                 if (mMovie != null) {
  103.                         int movieWidth = mMovie.width();
  104.                         int movieHeight = mMovie.height();

  105.                         /*
  106.                          * Calculate horizontal scaling
  107.                          */
  108.                         float scaleH = 1f;
  109.                         int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);

  110.                         if (measureModeWidth != MeasureSpec.UNSPECIFIED) {
  111.                                 int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
  112.                                 if (movieWidth > maximumWidth) {
  113.                                         scaleH = (float) movieWidth / (float) maximumWidth;
  114.                                 }
  115.                         }

  116.                         /*
  117.                          * calculate vertical scaling
  118.                          */
  119.                         float scaleW = 1f;
  120.                         int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);

  121.                         if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
  122.                                 int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
  123.                                 if (movieHeight > maximumHeight) {
  124.                                         scaleW = (float) movieHeight / (float) maximumHeight;
  125.                                 }
  126.                         }

  127.                         /*
  128.                          * calculate overall scale
  129.                          */
  130.                         mScale = 1f / Math.max(scaleH, scaleW);

  131.                         mMeasuredMovieWidth = (int) (movieWidth * mScale);
  132.                         mMeasuredMovieHeight = (int) (movieHeight * mScale);

  133.                         setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);

  134.                 } else {
  135.                         /*
  136.                          * No movie set, just set minimum available size.
  137.                          */
  138.                         setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
  139.                 }
  140.         }

  141.         @Override
  142.         protected void onLayout(boolean changed, int l, int t, int r, int b) {
  143.                 super.onLayout(changed, l, t, r, b);

  144.                 /*
  145.                  * Calculate left / top for drawing in center
  146.                  */
  147.                 mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;
  148.                 mTop = (getHeight() - mMeasuredMovieHeight) / 2f;
  149.                 
  150.                 mVisible = getVisibility() == View.VISIBLE;
  151.         }

  152.         @Override
  153.         protected void onDraw(Canvas canvas) {
  154.                 if (mMovie != null) {
  155.                         if (!mPaused) {
  156.                                 updateAnimationTime();
  157.                                 drawMovieFrame(canvas);
  158.                                 invalidateView();
  159.                         } else {
  160.                                 drawMovieFrame(canvas);
  161.                         }
  162.                 }
  163.         }
  164.         
  165.         /**
  166.          * Invalidates view only if it is visible.
  167.          * <br>
  168.          * {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher.
  169.          * 
  170.          */
  171.         @SuppressLint("NewApi")
  172.         private void invalidateView() {
  173.                 if(mVisible) {
  174.                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
  175.                                 postInvalidateOnAnimation();
  176.                         } else {
  177.                                 invalidate();
  178.                         }
  179.                 }
  180.         }

  181.         /**
  182.          * Calculate current animation time
  183.          */
  184.         private void updateAnimationTime() {
  185.                 long now = android.os.SystemClock.uptimeMillis();

  186.                 if (mMovieStart == 0) {
  187.                         mMovieStart = now;
  188.                 }

  189.                 int dur = mMovie.duration();

  190.                 if (dur == 0) {
  191.                         dur = DEFAULT_MOVIEW_DURATION;
  192.                 }

  193.                 mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
  194.         }

  195.         /**
  196.          * Draw current GIF frame
  197.          */
  198.         private void drawMovieFrame(Canvas canvas) {

  199.                 mMovie.setTime(mCurrentAnimationTime);

  200.                 canvas.save(Canvas.MATRIX_SAVE_FLAG);
  201.                 canvas.scale(mScale, mScale);
  202.                 mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
  203.                 canvas.restore();
  204.         }
  205.         
  206.         @SuppressLint("NewApi")
  207.         @Override
  208.         public void onScreenStateChanged(int screenState) {
  209.                 super.onScreenStateChanged(screenState);
  210.                 mVisible = screenState == SCREEN_STATE_ON;
  211.                 invalidateView();
  212.         }
  213.         
  214.         @SuppressLint("NewApi")
  215.         @Override
  216.         protected void onVisibilityChanged(View changedView, int visibility) {
  217.                 super.onVisibilityChanged(changedView, visibility);
  218.                 mVisible = visibility == View.VISIBLE;
  219.                 invalidateView();
  220.         }
  221.         
  222.         @Override
  223.         protected void onWindowVisibilityChanged(int visibility) {
  224.                 super.onWindowVisibilityChanged(visibility);
  225.                 mVisible = visibility == View.VISIBLE;
  226.                 invalidateView();
  227.         }
  228. }
复制代码
布局文件
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3. <font color="#ff0000">    xmlns:custom="http://schemas.android.com/apk/res-auto"</font>
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:paddingBottom="@dimen/activity_vertical_margin"
  7.     android:paddingLeft="@dimen/activity_horizontal_margin"
  8.     android:paddingRight="@dimen/activity_horizontal_margin"
  9.     android:paddingTop="@dimen/activity_vertical_margin"
  10.     tools:context=".MainActivity" >
  11.     <com.basv.gifmoviewview.widget.GifMovieView 
  12.             android:id="@+id/gif"
  13.             android:layout_height="wrap_content"
  14.         android:layout_width="fill_parent" 
  15.         android:layout_centerInParent="true"
  16. <font color="#ff0000">        android:onClick="onGifClick" 
  17.         custom:gif="@drawable/gif_005"</font> />

  18. </RelativeLayout>
复制代码
values/attrs.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.     <declare-styleable name="GifMoviewView">
  4.         <attr name="gif" format="reference" />
  5.         <attr name="paused" format="boolean" />
  6.     </declare-styleable>
  7.     <declare-styleable name="CustomTheme">
  8.         <attr name="gifMoviewViewStyle" format="reference" />
  9.     </declare-styleable>
  10. </resources>
复制代码

在values/styles里加上
<style name="Widget.GifMoviewView" parent="@android:style/Widget"></style>

接下来是Activity
  1. public class MainActivity extends Activity {

  2.         GifMovieView gif;
  3.         @Override
  4.         protected void onCreate(Bundle savedInstanceState) {
  5.                 super.onCreate(savedInstanceState);
  6.                 setContentView(R.layout.activity_main);
  7.                 gif= (GifMovieView) findViewById(R.id.gif);
  8.                 //可以动态添加
  9. //                gif.setMovieResource(R.drawable.gif_005);
  10.         }
  11.         /*
  12.          * 点击gif让其暂停或开始。
  13.          * 如果不想要可以去掉xml中的onClick属性
  14.          */
  15.         public void onGifClick(View v) {
  16.                 GifMovieView gif = (GifMovieView) v;
  17.                 gif.setPaused(!gif.isPaused());
  18.         }
  19.         @Override
  20.         public boolean onCreateOptionsMenu(Menu menu) {
  21.                 getMenuInflater().inflate(R.menu.main, menu);
  22.                 return true;
  23.         }
  24.         
  25. }
复制代码



1.gif (50.37 KB, 下载次数: 0)

1.gif

我的地址:http://www.eoeandroid.com/thread-551495-1-1.html
0 0