Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
2016-02-14 11:03
781 查看
Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还是要追究一下原理怎么做的,我们新建一个GifLibrary,然后右键Properties——Android,我们把架包勾上然后我们新建一个类GifSurfaceView继承自SurfaceView并且实现它的Callback接口
GifSurfaceView
[code]package com.lgl.giflibrary; import java.io.IOException; import java.io.InputStream; import java.net.URL; import android.content.Context; import android.graphics.Canvas; import android.graphics.Movie; import android.os.Handler; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; /** * 自定义Gif动画引擎 SurfaceView的实现主要是实现高速预览 我们将GIF图片绘制在SurfaceView上 * * @author LGL * */ public class GifSurfaceView extends SurfaceView implements Callback { // 监听 private SurfaceHolder holder; // 影片类 private Movie movie; // 输入流 private InputStream is = null; // 缩放 private float zoom = 1f; // 图片路径 private String path; // 判断是否网络读取 private boolean isNet = false; // 逐步播放 private Handler handler = new Handler(); private Runnable run = new Runnable() { @Override public void run() { // 不断绘制 Canvas canvas = holder.lockCanvas(); // 绘制的时候进行缩放比例,不影响下次绘图操作 canvas.save(); canvas.scale(zoom, zoom); movie.draw(canvas, 0, 0); canvas.restore(); holder.unlockCanvasAndPost(canvas); // 开始绘制 movie.setTime((int) (System.currentTimeMillis() % movie.duration())); handler.removeCallbacks(run); // 下次还用这个线程 handler.postDelayed(run, 30); } }; // 构造方法 public GifSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); holder = getHolder(); holder.addCallback(this); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { try { // 判断读取方法 if (isNet) { is = new URL(path).openConnection().getInputStream(); } else { // 本地读取文件 is = getContext().getAssets().open(path); } // 读取流 movie = Movie.decodeStream(is); // 设置SurfaceView的宽高 int width = movie.width(); int height = movie.height(); setMeasuredDimension((int) (width * zoom), (int) (height * zoom)); // 播放gif的帧动画 handler.post(run); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } // 初始化完成 @Override public void surfaceCreated(SurfaceHolder holder) { // 读取影片流 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { // SurfaceView被销毁时结束线程 handler.removeCallbacks(run); } public void setZoom(float zoom) { this.zoom = zoom; } public void setPath(String path) { this.path = path; } public void setNet(boolean isNet) { this.isNet = isNet; } }
layout_main.xml
[code] <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" android:gravity="center" > <com.lgl.giflibrary.GifSurfaceView android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
这里不难看出,我们判断了两种方法,从网络加载还是本地加载,并且缩放比例是多少,那我们就来使用一下,我们直接新建一个项目GifDemo,同样的右键Properties——Android,然后add一个库
layout_main.xml
[code]<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.lgl.giflibrary.GifSurfaceView android:id="@+id/gsv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" /> </RelativeLayout>
然后我们就来在MainActivity中使用
[code]//初始化 private GifSurfaceView gsv; gsv = (GifSurfaceView) findViewById(R.id.gsv); // 设置路径,这个路径实际上在library中是课更改的,我们在assets目录下放置一张gif图片 gsv.setPath("phont.gif"); // 设置缩放大小 gsv.setZoom(2f);
我们来运行一下
当然,如果是网上下载的,这个时候也我们可以用我们之前搭建的tomcat服务器测试一下
[code] gsv = (GifSurfaceView) findViewById(R.id.gsv); // 设置路径 // gsv.setPath("photo.gif"); // 设置缩放大小F gsv.setZoom(2f); // 如果是网络,记得添加权限 gsv.setNet(true); gsv.setPath("http://localhost:8080/lgl/photo.gif");
截图都是一样的,好的,这个博客只是说我们先脑子里又这么一个概念,让我们更容易接受以后我们天马行空的想法的基础,这个libray要是真的放到项目中去还是有点欠缺火候,很多地方都不完善,只是作为一个演示的作用,Demo就不提供了,就这么一点点,当然你要是想要也可以评论一下
相关文章推荐
- Android多国语言文件夹命名
- Android百度地图自定义公交路线导航
- Android开发学习之路--UI之简单聊天界面
- Android事件传递机制【Touch事件】
- android Fragment(Android官方文档中文版)
- GitHub Android 最火开源项目Top20
- Android云测试
- Android--SoftReference缓存图片
- 根据ViewPager中图片的宽度,算出滚动条的宽度,并且在ViewPager上执行平移动画
- Android 计算当前使用内存百分比的方法
- Android 基本布局
- Android Studio更新升级方法
- Android Studio更新升级方法
- Android Studio 导入第三方jar包
- android中常用的finish()与onDestroy()的区别
- Android定位&地图&导航——自定义公交路线代码
- 关于Android studio 使用极光推送,集成成功,但是推送不成功的问题
- android:Activity启动模式之singleTask(一)
- Android 使用android-support-multidex解决Dex超出方法数的限制问题
- 居中滚动的scrollview