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动画,自己实现功能的初体现的更多相关文章

  1. Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷

    Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...

  2. Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系

    Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 现在的二维码可谓是烂大街了,到处都是二维码,什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...

  3. Android高级控件(三)——&#160;使用Google ZXing实现二维码的扫描和生成相关功能体系

    Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 如今的二维码可谓是烂大街了.到处都是二维码.什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...

  4. Android 高级控件(七)——RecyclerView的方方面面

    Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...

  5. Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现

    Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...

  6. Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例

    Android高级控件(五)--如何打造一个企业级应用对话列表,以QQ,微信为例 看标题这么高大上,实际上,还是运用我么拿到listview去扩展,我们讲什么呢,就是研究一下QQ,微信的这种对话列表, ...

  7. Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...

  8. Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,添加和删除等功能 这个控件还是挺复杂的.也是项目中应该算是比較经常使用的了,所以写了一个小Demo来讲讲,主要是自己定义a ...

  9. Android高级控件--AdapterView与Adapter

    在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...

随机推荐

  1. Redis 学习笔记4: Redis 3.2.1 集群搭建

    在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...

  2. android 缓存实现

    1.之前因为做一个项目的过程中遇到要频繁重复下载的文件比如图片等,需要在本地缓存,除了用户体验也保证了省流量. 这个demo是用下载网络图片来演示. 一共有六张网络图片,加载图片时,会判断图片是否下载 ...

  3. SQL Server 执行计划操作符详解(1)——断言(Assert)

    前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很 ...

  4. 6.0、Android Studio性能优化工具

    显示图像包含四个步骤.简单来说,CPU对比显示列表,GPU渲染图片显示,内存存储图片和数据,电池提供点力能源.每个部分的硬件都有限制,超过这个限制会导致应用运行较慢,显示性能差,或者耗电. 为了查找造 ...

  5. Objc中处理数组越界的一种办法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Objc的数组如果在访问时索引非法,则会抛出NSRangeEx ...

  6. 最简单的基于FFmpeg的编码器-纯净版(不包含libavformat)

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  7. Nginx模块之SessionSticky

    0 工作原理 Session Sticky 模块在upstream 返回响应后,向客户的浏览器写入 Cookie ,默认名为route ,保存的内容是一个 md5 码. 之后,模块接收到客户浏览器的请 ...

  8. Tomcat性能优化及常用命令整理

    1汤姆猫性能优化 1.1连接参数 1.1.1默认连接配置 默认连接器采用阻塞式 IO,默认最大线程数为200,配置如下: <Connector port="8080" pro ...

  9. UNIX网络编程——使用select 实现套接字I/O超时

    下面程序包含read_timeout.write_timeout.accept_timeout.connect_timeout 四个函数封装: /* read_timeout - 读超时检测函数,不含 ...

  10. 后端分布式系列:分布式存储-MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适.最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类.结合实际工作中碰到的问题,以寻找答案的方式来剖 ...