Android SurfaceView 是Android系统中的高级组件,它有自己的绘制界面,可以在一个独立的线程进行UI的绘制, 因此不会阻塞主线程,这也是我们使用SuefaceView播放gif图片的原因。
先简单说一下思路,gif图其实就是由一帧一帧的图片组成,当我们想要播放gif的时候,其实就是播放gif的每一帧,这样我们只需要解决三个问题就可以实现gif的播放 1.gif一共有多少帧; 2.随时间的推移寻找对应的那一帧; 3.播放该帧. Android中有一个Moive类,Moive其实就是电影么,这个类中提供的方法可以很好的解决这三个问题。 比如 movie.duration() 可以获取一共有多少帧, movie.setTime()显示哪一帧。
已下是代码,关键代码已经注释
public class GifSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private String path = "test.gif"; private Movie movie; // 缩放系数 private float zoom = 2; // 执行 gif动画 private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { // gif动画 是由一帧 的图片组成,实现 gif动画就是将 一帧帧的图 画出来, // 首先获取画布 Canvas canvas = holder.lockCanvas(); // 保存当前画布状态(此处保存画布状态 是为了保证 不影响下一帧的 缩放---下方 有 恢复状态) canvas.save(); canvas.scale(zoom, zoom); //设置画布 movie.draw(canvas, 0, 0); //逐帧绘制图片 //这里使用时间戳 与总帧数 求余操作,这样 随着时间的推移计算出该播放哪一帧 movie.setTime((int) (System.currentTimeMillis() % movie.duration())); // 恢复之前保存的状态 canvas.restore(); holder.unlockCanvasAndPost(canvas); // 循环执行 handler.postDelayed(runnable, 50); } }; public GifSurfaceView(Context context) { super(context); initData(); } public GifSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); initData(); } public GifSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initData(); } private void initData() { holder = getHolder(); holder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } /** *测量组件,设置 组件的宽高 *之所有 将Moive 的初始化放在这里是因为surfaceView再 默认情况下是填充满 父组件的 *设置SurfaceView的宽高 和gif宽高保持一致 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // surfaceView 默认情况下 填充满 父组件 //加载gif图片 try { InputStream open = getContext().getAssets().open(path); // 使用影片对象 处理gif图片 movie = Movie.decodeStream(open); // 获取 move对象的宽高(实际为gif 的宽高) int width = movie.width(); int height = movie.height(); // 设置surfaceView组件的宽高 使其保持 和 gif图的宽高一致 setMeasuredDimension((int) (width * zoom), (int) (height * zoom)); } catch (IOException e) { } } public float getZoom() { return zoom; } public void setZoom(float zoom) { this.zoom = zoom; } // 开始执行gif动画 public void start() { handler.post(runnable); } // 开始执行gif动画 public void stop() { handler.removeCallbacks(runnable); }
查看更多关于Android SurfaceView 播放gif的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did129271