亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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)文章

  • 詳解Android中IntentService的使用方法

    詳解Android中IntentService的使用方法

    這篇文章主要介紹了Android中IntentService的使用方法,需要的朋友可以參考下
    2015-12-12
  • Android實現(xiàn)紙飛機的簡單操作

    Android實現(xiàn)紙飛機的簡單操作

    這篇文章主要為大家詳細介紹了Android實現(xiàn)紙飛機的簡單操作,類似于漂流瓶功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Android LayoutInflater中 Inflate()方法應(yīng)用

    Android LayoutInflater中 Inflate()方法應(yīng)用

    本文主要介紹Android 中Inflate 方法的用法, 在開發(fā)Android應(yīng)用過程中,可以在程序中應(yīng)用 Inflate()方法加載新布局,希望能幫助有需要的朋友
    2016-07-07
  • Android自定義實現(xiàn)頂部粘性下拉刷新效果

    Android自定義實現(xiàn)頂部粘性下拉刷新效果

    這篇文章主要為大家詳細介紹了Android自定義實現(xiàn)頂部粘性下拉刷新效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 淺談React Native打包apk的坑

    淺談React Native打包apk的坑

    下面小編就為大家?guī)硪黄獪\談React Native打包apk的坑。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Android View類與SurfaceView類詳解

    Android View類與SurfaceView類詳解

    本文主要介紹Android View類與SurfaceView類,這里提供了詳細的Android View類和SurfaceView類的使用方法,有興趣的小伙伴可以參考下
    2016-08-08
  • 詳解Android數(shù)據(jù)存儲之SQLCipher數(shù)據(jù)庫加密

    詳解Android數(shù)據(jù)存儲之SQLCipher數(shù)據(jù)庫加密

    對于已經(jīng)ROOT的手機來說的沒有任何安全性可以,一旦被利用將會導(dǎo)致數(shù)據(jù)庫數(shù)據(jù)的泄漏,本篇文章主要介紹了Android數(shù)據(jù)存儲之SQLCipher數(shù)據(jù)庫加密,具有一定的參考價值,有需要的可以了解一下。
    2016-12-12
  • Android編程模擬HOME鍵功能示例

    Android編程模擬HOME鍵功能示例

    這篇文章主要介紹了Android編程模擬HOME鍵功能的方法,結(jié)合實例形式分析了Android模擬HOME鍵的原理與相關(guān)事件操作技巧,需要的朋友可以參考下
    2016-10-10
  • android 把float轉(zhuǎn)換成Int的實例講解

    android 把float轉(zhuǎn)換成Int的實例講解

    今天小編就為大家分享一篇android 把float轉(zhuǎn)換成Int的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • android仿知乎標(biāo)題欄隨ScrollView滾動變色

    android仿知乎標(biāo)題欄隨ScrollView滾動變色

    這篇文章主要為大家詳細介紹了android仿知乎標(biāo)題欄隨ScrollView滾動變色,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06

最新評論