Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还是要追究一下原理怎么做的,我们新建一个GifLibrary,然后右键Properties——Android,我们把架包勾上
然后我们新建一个类GifSurfaceView继承自SurfaceView并且实现它的Callback接口
GifSurfaceView
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
<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
<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中使用
//初始化
private GifSurfaceView gsv;
gsv = (GifSurfaceView) findViewById(R.id.gsv);
// 设置路径,这个路径实际上在library中是课更改的,我们在assets目录下放置一张gif图片
gsv.setPath("phont.gif");
// 设置缩放大小
gsv.setZoom(2f);
我们来运行一下
当然,如果是网上下载的,这个时候也我们可以用我们之前搭建的tomcat服务器测试一下
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高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现的更多相关文章
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 现在的二维码可谓是烂大街了,到处都是二维码,什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 如今的二维码可谓是烂大街了.到处都是二维码.什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...
- Android 高级控件(七)——RecyclerView的方方面面
Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...
- Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现
Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...
- Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例
Android高级控件(五)--如何打造一个企业级应用对话列表,以QQ,微信为例 看标题这么高大上,实际上,还是运用我么拿到listview去扩展,我们讲什么呢,就是研究一下QQ,微信的这种对话列表, ...
- Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能
Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...
- Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能
Android高级控件(一)--ListView绑定CheckBox实现全选,添加和删除等功能 这个控件还是挺复杂的.也是项目中应该算是比較经常使用的了,所以写了一个小Demo来讲讲,主要是自己定义a ...
- Android高级控件--AdapterView与Adapter
在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...
随机推荐
- Basic Git commands
Basic Git commands Skip to end of metadata Created by Paul Watson [Atlassian], last modified on Nov ...
- SQL Server 执行计划操作符详解(3)——计算标量(Compute Scalar)
接上文:SQL Server 执行计划操作符详解(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介绍第 ...
- 剑指Offer——线程同步volatile与synchronized详解
(转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...
- Mybatis3.4.0不支持mybatis-spring1.2.5及以下版本
今天将工程的Mybatis的版本由3.3.0升级到3.4.0导致程序运行错误,使用的mybatis-spring版本是1.2.3,错误内容如下,最后发现是SpringManagedTransactio ...
- 【Android应用开发】 Android 崩溃日志 本地存储 与 远程保存
示例代码下载 : http://download.csdn.net/detail/han1202012/8638801; 一. 崩溃日志本地存储 1. 保存原理解析 崩溃信息本地保存步骤 : -- 1 ...
- hashmap 循环取出所有值 取出特定的值 两种方法
//第一种 Iterator menus = menu.iterator(); while(menus.hasNext()) { Map userMap = (Map) menus.next(); S ...
- 重载重写重定义-易混淆概念-C++编译器处理方式
1.函数重载 1)必须在同一个类中进行. 2)子类无法重载父类的函数,父类同名函数将被名称覆盖 3)重载是在编译期间根据参数类型和个数决定函数调用 2.函数重写 1)必须发生于父类与子类之间 2)并且 ...
- 1033. To Fill or Not to Fill (25) -贪心算法
题目如下: With highways available, driving a car from Hangzhou to any other city is easy. But since the ...
- Deep Learning with Torch
原文地址:https://github.com/soumith/cvpr2015/blob/master/Deep%20Learning%20with%20Torch.ipynb Deep Learn ...
- (NO.00002)iOS游戏精灵战争雏形(十二)
首先要声明的是,前几篇实现的shoot方法不是一定会命中目标,这取决于目标运行的速度,子弹的速度,子弹发射的时机以及弹道路径中是否有障碍物等等. 这也是符合实际情况的.如果你的要求是一旦发出子弹必定击 ...