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. Java 单元测试 JUnit4 快速入门

    JUnit最佳实践 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class CardServiceTest {     /**      * 最佳 ...

  2. app如何更换用户头像信息呢?不妨这样做

    对于现在的手机应用而言,要想获得更多的人的使用,就需要给用户更多的自由功能才行,这也是基于用户体验开发软件的核心思想,一切以用户为中心,想用户之所想,做用户之所需.今天我就来谈一谈刚学到的一个关于设置 ...

  3. 【Android应用开发】 Android 崩溃日志 本地存储 与 远程保存

    示例代码下载 : http://download.csdn.net/detail/han1202012/8638801; 一. 崩溃日志本地存储 1. 保存原理解析 崩溃信息本地保存步骤 : -- 1 ...

  4. Android对话框AlertDialog-android学习之旅(四十二)

    对话框简介 android提供了丰富的对话框支持,支持四种如下的对话框. AlertDialog简介 介绍上面六个方法的代码示例 setMessage() <?xml version=" ...

  5. Java五道输出易错题解析(进来挑战下)

    转自:http://blog.csdn.net/lanxuezaipiao/article/details/41985243 收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注 ...

  6. iOS中 扫描二维码/生成二维码详解 韩俊强的博客

    最近大家总是问我有没有关于二维码的demo,为了满足大家的需求,特此研究了一番,希望能帮到大家! 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 指示根视图: se ...

  7. Ubuntu 12.04: How to enable root login

    1. vi /etc/lightdm/lightdm.conf and add following modifications. greeter-show-manual-login=true allo ...

  8. UNIX网络编程——套接字选项(SOL_SOCKET级别)

    #include <sys/socket.h> int setsockopt( int socket, int level, int option_name,const void *opt ...

  9. Axure如何建立共享项目、如何编辑共享项目、如何获取共享项目

    如果小伙伴是一名编程工作者,我们不可以避免的会和Axure这块软件握手,但是但一个项目需要协同操作的时候,就需要用到项目共享的功能.类似我们的svn,想起机房合作的时候,每天早上来到427的我们,打开 ...

  10. 1025. PAT Ranking (25)

    题目如下: Programming Ability Test (PAT) is organized by the College of Computer Science and Technology ...