最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實現(xiàn)可播放GIF動畫的ImageView

 更新時間:2016年09月05日 10:35:25   作者:huaxun66  
這篇文章主要為大家詳細介紹了Android實現(xiàn)可播放GIF動畫的ImageView,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Android的原生控件并不支持播放GIF格式的圖片。我們都知道,在Android中如果想要顯示一張圖片,可以借助ImageView來完成,但是如果將一張GIF圖片設(shè)置到ImageView里,它只會顯示這張圖片的第一幀,不會產(chǎn)生任何的動畫效果。今天我們來編寫一個自定義的增強型ImageView(繼承ImageView),可以播放GIF格式的圖片,暫且叫做GifImageView吧。

1.自定義屬性

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
 <declare-styleable name="GifImageView"> 
  <attr name="auto_play" format="boolean"></attr> 
 </declare-styleable> 
</resources>

 2.自定義View中獲取屬性值

 private Movie mMovie;//播放動畫需要用到的,系統(tǒng)類
 private int mImageWidth;//動畫的imageview的寬度
 private int mImageHeight;//動畫imageview的高度
 private long mMovieStart = 0;// 播放開始
 private boolean isAutoPlay;//是否自動播放
 private Bitmap mStartPlay;//開始按鈕
 private boolean isPlaying=false;//記錄是否正在播放
 private float mScale;//圖片的縮放比
 private int mMeasuredGifWidth;//縮放后圖片寬
 private int mMeasuredGifHeight;//縮放后圖片高
 ...

 private void init(Context context, AttributeSet attrs) {
 TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.GifImageView);
 // 通過反射拿布局中src的資源id,所以gif文件需要放在布局的src中
 int resourceId = getResourceId(attributes, context, attrs);
 if (resourceId != 0) {
  // 說明是gif動畫
  // 1.將resourcesId變成流
  // 2.用Move來decode解析流
  // 3.獲得bitmap的長寬
  InputStream is = getResources().openRawResource(resourceId);
  mMovie = Movie.decodeStream(is);
  if (mMovie != null) {
  Bitmap bitmap = BitmapFactory.decodeStream(is);
  mImageWidth = bitmap.getWidth();
  mImageHeight = bitmap.getHeight();
  // 用完釋放
  bitmap.recycle();
  // 獲得是否允許自動播放,如果不允許自動播放,則初始化播放按鈕
  isAutoPlay = attributes.getBoolean(R.styleable.GifImageView_auto_play, false);
  if (!isAutoPlay) {
   mStartPlay = BitmapFactory.decodeResource(getResources(),R.drawable.start_play);
   setOnClickListener(this);
  }  
  }
 }
 //回收資源
 attributes.recycle();
 }

 /**
 * 通過反射拿布局中src的資源id
 * 
 * @param attrs
 * @param context
 * @param attributes
 */
 private int getResourceId(TypedArray attributes, Context context, AttributeSet attrs) {
 try {
  Field filed = TypedArray.class.getDeclaredField("mValue");
  filed.setAccessible(true);
  TypedValue typeValue = (TypedValue) filed.get(attributes);
  return typeValue.resourceId;
 } catch (Exception e) {
  e.printStackTrace();
 }
 }
 return 0;
}

3.重寫onMesure()

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 if (mMovie != null) {
  /*
   * Calculate horizontal scaling
   */
  float scaleW = 1f;
  int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);
  if (measureModeWidth != MeasureSpec.UNSPECIFIED) {
   int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
   scaleW = (float) mImageWidth / (float) maximumWidth;
  }
  /*
   * calculate vertical scaling
   */
  float scaleH = 1f;
  int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);
  if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
   int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
   scaleH = (float) mImageHeight / (float) maximumHeight;
  }
  /*
   * calculate overall scale
   */
  mScale = 1f / Math.max(scaleH, scaleW);
  mMeasuredGifWidth = (int) (mImageWidth * mScale);
  mMeasuredGifHeight = (int) (mImageHeight * mScale);
  setMeasuredDimension(mMeasuredGifWidth, mMeasuredGifHeight);
 }
 }

4.重寫onDraw()

 @Override
 protected void onDraw(Canvas canvas) {
 if (mMovie == null) {
  // mMovie等于null,說明是張普通的圖片,則直接調(diào)用父類的onDraw()方法
  super.onDraw(canvas);
 } else {
  // mMovie不等于null,說明是張GIF圖片
  if (isAutoPlay) {
  // 如果允許自動播放,就播放
  playMovie(canvas);
  invalidate();
  } else {
  // 不允許自動播放的話
  // 1.判斷是否正在播放
  // 2.獲得第一幀的圖像
  // 3.然后添加播放按鈕
  if (isPlaying) {
   // 如果正在播放就playmoive繼續(xù)播放
   if (playMovie(canvas)) {
   isPlaying = false;
   }
   invalidate();
  } else {
   // 第一幀
   mMovie.setTime(0);
   canvas.save(Canvas.MATRIX_SAVE_FLAG);
   canvas.scale(mScale, mScale);
   mMovie.draw(canvas, 0, 0);// 畫
   canvas.restore();
   // 繪制開始按鈕
   int offsetW = (mMeasuredGifWidth - mStartPlay.getWidth()) / 2;
   int offsetH = (mMeasuredGifHeight - mStartPlay.getHeight()) / 2;
   canvas.drawBitmap(mStartPlay, offsetW, offsetH, null);
  }
  }
 }
 }

 /**
 * 播放gif動畫
 * 
 * @param canvas
 */
 private boolean playMovie(Canvas canvas) {
 // 1.獲取播放的時間
 // 2.如果開始start=0,則認為是開始
 // 3.記錄播放的時間
 // 4.設(shè)置進度
 // 5.畫動畫
 // 6.如果時間大于了播放的時間,則證明結(jié)束
 long now = SystemClock.uptimeMillis();
 if (mMovieStart == 0) {
  mMovieStart = now;
 }
 int duration = mMovie.duration();
 if (duration == 0) {
  duration = 1000;
 }
 //記錄gif播放了多少時間
 int relTime = (int) ((now - mMovieStart) % duration);
 mMovie.setTime(relTime);// 設(shè)置時間
 canvas.save(Canvas.MATRIX_SAVE_FLAG);
 canvas.scale(mScale, mScale);
 mMovie.draw(canvas, 0, 0);// 畫
 canvas.restore();
 if ((now - mMovieStart) >= duration) {
  // 結(jié)束
  mMovieStart = 0;
  return true;
 }
 return false;
 }

5.添加點擊事件

 @Override
 public void onClick(View v) {
 if(v.getId()==getId()){
  isPlaying=true;
  invalidate();
 }
 }

還有一點需要注意,有些4.0以上系統(tǒng)的手機啟動了硬件加速功能之后會導(dǎo)致GIF動畫播放不出來,因此我們需要在AndroidManifest.xml中去禁用硬件加速功能,可以通過指定android:hardwareAccelerated=false來完成。

--------------------------------------------------------------------------------

現(xiàn)在我們來看看運行后效果如何吧,
布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 xmlns:attr="http://schemas.android.com/apk/res/com.hx.gifimageview"
 android:id="@+id/container"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <com.hx.gifimageview.GifImageView
  android:layout_width="150dip"
  android:layout_height="150dip"
  android:layout_margin="10dp"
  android:src="@drawable/shulan"
  attr:auto_play="false" />

 <com.hx.gifimageview.GifImageView
  android:layout_width="150dip"
  android:layout_height="150dip"
  android:layout_margin="10dp"
  android:src="@drawable/shulan"
  attr:auto_play="true" />

 <com.hx.gifimageview.GifImageView
  android:layout_width="150dip"
  android:layout_height="150dip"
  android:layout_margin="10dp"
  android:src="@drawable/jingtai"
  attr:auto_play="true" />
</LinearLayout>

 

圖一的auto_play屬性為false,會顯示第一幀和一個播放按鈕,點擊后Gif圖片會自動運行。
圖二的auto_play屬性為true,會自動循環(huán)播放Gif。
圖三我們給的資源是靜態(tài)圖片,因為自定義View繼承ImageView,所以具備ImageView所有特性,因此也能顯示靜態(tài)圖片。

源碼下載:http://xiazai.jb51.net/201609/yuanma/GifImageView(jb51.net).rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

突泉县| 巫溪县| 南郑县| 上栗县| 绥滨县| 胶南市| 沐川县| 五寨县| 灵宝市| 蓝田县| 平泉县| 乌拉特中旗| 汪清县| 宜黄县| 天峨县| 潼关县| 泰宁县| 丹江口市| 陇川县| 巴里| 西丰县| 盖州市| 黑山县| 申扎县| 徐州市| 扎赉特旗| 瑞金市| 明溪县| 拉萨市| 定南县| 湟中县| 资中县| 襄城县| 江孜县| 稻城县| 武冈市| 和林格尔县| 涟源市| 双鸭山市| 区。| 宝应县|