向glide致敬,自己写Gif动图加载框架

用Glide很久了。除了对他膜拜就是膜拜,尤其是它可以实现gif的动态加载,那么我们今天就自己来实现以下如何动态的显示Gif。最后要提一句这个思路呢是从动脑学院得知的。他们是一个很牛逼的培训团体。希望广而告之

上图片
这里写图片描述

实现功能

  • 1,加载本地gif
  • 2,加载网络gif

用到技术

  • 1,movie类
  • 2,canvas类的绘制
  • 3,网络下载

都是最简单的方法来实现逼格的效果

实现原理

gif就是一个无声的电影,你把电影的每一帧都会知道imageview上去就不分分钟了么

不就用到了canvas绘制一个gif大小的bigmap。然后在吧bitmap放到imageview里面去。
网络加载图片,就是查找本地是否有该gif,如果没有就先下载然后在从本地导入。

废话不多说直接上代码

package example.com.gifloader;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

import example.com.gifloader.core.GifDecoder;

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;
    public static String url = "http://image.haha.mx/2014/02/02/middle/1115779_c221d1fc47b97bb1605cddc9c8aec0a7_1391347675.gif";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.iv);
        try {
            GifDecoder.with(this).load(url).into(imageView);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

和glide是不是很像就一句话 GifDecoder.with(this).load(url).into(imageView);

package example.com.gifloader.core;

import android.content.Context;
import android.net.Uri;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * Created by wanghao on 16/5/23.
 * 加载gif
 */
public class GifDecoder {
    public static Context context;

    public static class Gif {
        public static GifDecoder instance = new GifDecoder();
    }

    public static GifDecoder with(Context c) {
        context = c;
        return Gif.instance;
    }


    /**
     * load gif file form inputstream
     */
    public GifDrawer load(InputStream is) {
        GifDrawer drawer = new GifDrawer();
        drawer.setIs(is);
        return drawer;
    }

    /**
     * load gif file form uri
     */
    public GifDrawer load(Uri uri) {
        InputStream is = null;
        try {
            is = context.getContentResolver().openInputStream(uri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return load(is);
    }

    /**
     * load gif file form sdcard
     */
    public GifDrawer load(File file) {
        FileInputStream is = null;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return load(is);
    }

    /**
     * load gif file form url
     */
    public GifDrawer load(String url) {
        String name = MD5Utils.string2MD5(url);
        System.out.println(name);
        FileInputStream is = null;
        String path = context.getExternalCacheDir() + File.separator + name;

        File file = new File(path);
        if (file.exists()) {
            try {
                is = new FileInputStream(file);
                return load(is);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
//           不存在 先下载下来
            GifDrawer gifDrawer = new GifDrawer();
            GifLoaderTask loadGifTask = new GifLoaderTask(gifDrawer, context);
            loadGifTask.execute(url);
            return gifDrawer;
        }

        return load(is);
    }


}
package example.com.gifloader.core;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Handler;
import android.widget.ImageView;

import java.io.InputStream;

/**
 * Created by wanghao on 16/5/23.
 * gif的绘制
 */
public class GifDrawer {
    private static final String TAG = "GifDrawer";
    private InputStream is;
    private ImageView imageView;
    private Movie movie;
    private Bitmap bitmap;
    private Canvas canvas;
    private Handler handler = new Handler();
    private final long delayMills = 16;
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            draw();
            handler.postDelayed(runnable, delayMills);
        }
    };

    private void draw() {
        canvas.save();
        movie.setTime((int) (System.currentTimeMillis() % movie.duration()));//这个是获取movie的某一帧,我们就不断地循环它
        movie.draw(canvas, 0, 0);
        imageView.setImageBitmap(bitmap);
        canvas.restore();
    }

    /**
     * 传递imagerview,将gif放到gif中去
     *
     * @param imageView
     */
    public void into(ImageView imageView) {
        this.imageView = imageView;
        if (is == null) {
            return;
        } else if (imageView == null) {

            throw new RuntimeException("imagetView can not be null");
        } else {

//            开始在imageview里面绘制电影
            movie = Movie.decodeStream(is);//gif小电影
            if (movie == null) {
                throw new IllegalArgumentException("Illegal gif file");

            }
            if (movie.width() <= 0 || movie.height() <= 0) {
                return;
            }
//            需要bitmap
            bitmap = Bitmap.createBitmap(movie.width(), movie.height(), Bitmap.Config.RGB_565);
            canvas = new Canvas(bitmap);
//            准备把canvas的小电影显示在imageview里面
            handler.post(runnable);
        }
    }

    public InputStream getIs() {
        return is;
    }

    public void setIs(InputStream is) {
        this.is = is;
    }

    public ImageView getImageView() {
        return imageView;
    }

    public void setImageView(ImageView imageView) {
        this.imageView = imageView;
    }
}
package example.com.gifloader.core;

import android.content.Context;
import android.os.AsyncTask;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by wanghao on 16/5/23.
 */
class GifLoaderTask extends AsyncTask<String, Void, String> {
    private final Context context;
    private String name;

    private GifDrawer gifDrawer;

    public GifLoaderTask(GifDrawer gifDrawer, Context context) {
        this.gifDrawer = gifDrawer;
        this.context = context;
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            System.out.println(params[0]);
            name = MD5Utils.string2MD5(params[0]);
            System.out.println("--" + name);

            InputStream is = HttpLoader.getInputStreanFormUrl(params[0]);
            String path = context.getExternalCacheDir() + File.separator + name;
            File file = new File(path);

            FileOutputStream fops = new FileOutputStream(file);

            int len = 0;
            byte[] buffer = new byte[1024];
            while ((len = is.read(buffer)) != -1) {
                fops.write(buffer, 0, len);
            }
            fops.close();
            is.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return params[0];
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (s != null) {
            GifDecoder.with(context).load(s).into(gifDrawer.getImageView());
        }
    }
}

如果觉得async很low的可以用其他方法。反正现在下载方法很多。一个意思

代码在github上:https://github.com/wanghao200906/GifLoader

尊重原创:http://blog.csdn.net/wanghao200906/article/details/51483345

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值