最近项目里有个需求,要加载GifView,当传入的是普通的图片时也能正常展示普通图片。从网上找了几个现成的GifView都不能很好的满足需求,就自己写了一个,顺便学习了下自定义View。
第一次写难免存在缺陷,希望大家批评指正。废话不多说,直接上代码:
1 import android.content.Context; 2 import android.graphics.Bitmap; 3 import android.graphics.Canvas; 4 import android.graphics.Movie; 5 import android.os.Handler; 6 import android.util.AttributeSet; 7 import android.util.Log; 8 import android.view.View; 9 import android.widget.ImageView; 10 11 12 /** 13 * Created by stridercheng on 2015/7/21. 14 * 15 */ 16 public class GifView extends ImageView { 17 private long mMovieStart; 18 private Movie mMovie; 19 private final static String TAG = "MyView"; 20 private Bitmap bp; 21 private float startDrawX, startDrawY; 22 private Handler handler = new Handler() { 23 public void handleMessage(android.os.Message msg) { 24 if (msg.what == 0x123) { 25 invalidate(); 26 } 27 }; 28 }; 29 30 public GifView(Context context, AttributeSet attrs) { 31 super(context, attrs); 32 this.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 33 } 34 35 @Override 36 protected void onDraw(Canvas canvas) { 37 Log.i(TAG, "---->onDraw"); 38 //普通图片mMovie是空的,直接调用超类的onDraw方法 39 if (mMovie == null) { 40 super.onDraw(canvas); 41 } else { 42 long now = android.os.SystemClock.uptimeMillis(); 43 44 // 开始播放的时间 45 if (mMovieStart == 0) { 46 mMovieStart = now; 47 } 48 if (mMovie != null) { 49 50 int dur = mMovie.duration(); 51 if (dur == 0) { 52 dur = 1000; 53 } 54 int relTime = (int) ((now - mMovieStart) % dur); 55 mMovie.setTime(relTime); 56 mMovie.draw(canvas, startDrawX, startDrawY); 57 //设置50ms播放间隔 58 handler.sendEmptyMessageDelayed(0x123, 50); 59 } 60 } 61 } 62 63 @Override 64 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 65 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 66 if (mMovie != null) { 67 //设置gif绘制的坐标原点 68 startDrawX = this.getWidth() / 2 - mMovie.width() / 2; 69 startDrawY = this.getHeight() / 2 - mMovie.height() / 2; 70 } 71 } 72 73 /** 74 * 75 * @description 76 * @author stridercheng 77 * @date 2015-7-21 78 */ 79 public void setFilePath(String filePath) { 80 try { 81 //从文件中获取Gif 82 mMovie = Movie.decodeFile(filePath); 83 if (mMovie == null) { 84 //根据谷歌推荐的方式加载普通图片 85 ImageProcess imgp = new ImageProcess(); 86 bp = imgp.getSmallBitmap(filePath); 87 this.setImageBitmap(bp); 88 } 89 } catch (Exception e) { 90 e.printStackTrace(); 91 } 92 invalidate(); 93 } 94 }
附上ImageProcess的源码:
/** * 获取指定高宽的图像 * @description * @author stridercheng * @date 2015-7-22 */ public Bitmap getSmallBitmap(String filePath) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); options.inSampleSize = calculateInSampleSize(options, 480, 800); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(filePath, options); } /** * 此处是引用了谷歌官方的图像处理方式,如不明白,可以查看官方文档的处理大图片相关文档 * @description * @author stridercheng * @date 2015-7-22 */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; }