Android,GIF 애니메이션 재생 가능 한 ImageView 구현

8414 단어 AndroidGIFImageView
Android 의 네 이 티 브 컨트롤 은 GIF 형식의 그림 을 재생 하 는 것 을 지원 하지 않 습 니 다.안 드 로 이 드 에서 그림 을 표시 하려 면 ImageView 를 통 해 완성 할 수 있다 는 것 을 잘 알 고 있 습 니 다.그러나 GIF 그림 을 ImageView 에 설정 하면 이 그림 의 첫 번 째 프레임 만 표시 되 고 애니메이션 효과 가 나타 나 지 않 습 니 다.오늘 은 GIF 형식의 그림 을 재생 할 수 있 는 사용자 정의 증강 형 ImageView(ImageView 계승)를 만 듭 니 다.잠시 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.사용자 정의 뷰 에서 속성 값 가 져 오기

 private Movie mMovie;//         ,   
 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,         ,        onDraw()  
  super.onDraw(canvas);
 } else {
  // mMovie   null,    GIF  
  if (isAutoPlay) {
  //         ,   
  playMovie(canvas);
  invalidate();
  } else {
  //          
  // 1.        
  // 2.        
  // 3.        
  if (isPlaying) {
   //        playmoive    
   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.    
 // 5.   
 // 6.            ,     
 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);//     
 canvas.save(Canvas.MATRIX_SAVE_FLAG);
 canvas.scale(mScale, mScale);
 mMovie.draw(canvas, 0, 0);//  
 canvas.restore();
 if ((now - mMovieStart) >= duration) {
  //   
  mMovieStart = 0;
  return true;
 }
 return false;
 }
5.클릭 이벤트 추가

 @Override
 public void onClick(View v) {
 if(v.getId()==getId()){
  isPlaying=true;
  invalidate();
 }
 }
그리고 주의해 야 할 것 은 4.0 이상 의 시스템 의 핸드폰 이 하드웨어 가속 기능 을 시작 한 후에 GIF 애니메이션 이 재생 되 지 못 할 수 있 기 때문에 우 리 는 AndroidManifest.xml 에서 하드웨어 가속 기능 을 사용 하지 않 고 지정 한 android:hardwareAccelerated=false 를 통 해 완성 할 수 있 습 니 다.
--------------------------------------------------------------------------------
이제 운행 후 효과 가 어떤 지,
레이아웃 파일:

<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>

 
그림 1 의 autoplay 속성 은 false 입 니 다.첫 번 째 프레임 과 재생 단 추 를 표시 합 니 다.클릭 하면 Gif 그림 이 자동 으로 실 행 됩 니 다.
그림 2 의 autoplay 속성 이 true 이면 자동 으로 Gif 를 재생 합 니 다.
그림 3 우리 가 준 자원 은 정적 이미지 입 니 다.사용자 정의 View 가 ImageView 를 계승 하기 때문에 ImageView 의 모든 특성 을 가지 기 때문에 정적 이미지 도 표시 할 수 있 습 니 다.
원본 다운로드:http://xiazai.jb51.net/201609/yuanma/GifImageView(jb51.net).rar
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기