QQ聊天之Android显示Gif 您所在的位置:网站首页 qq大的动态表情 QQ聊天之Android显示Gif

QQ聊天之Android显示Gif

2024-06-25 14:52| 来源: 网络整理| 查看: 265

好久没有对这一系列进行更新了,不知道各位亲的Android功力有没有更上一层楼?本来并没有打算在这段时间发表新的博客,但是由于这一两天找到了一个能够让Android上显示Gif图片的方法,这样一来,寒假里没有解决的QQ添加动态表情的问题便有了一个初步的解决方法。下面进入正题~ PS:本讲源码地址在文末。

     本节的目标是对TextView进行修改,最终实现在TextView插入动态图片的效果。QQ聊天界面的动态表情、大表情、或者一些第三方的动态图就是实现了这个效果。

     老规矩首先上一个效果图:

     

    那两只小鸡其实都是动图,只不过这里不好发Gif,你也可以注意到左右两图的小黄鸡是不一样的,说明它在动~

     然后讲一下基本原理:

     谷歌官方并没有给出Gif的显示控件(虽然我想在高霸上的谷歌眼中这不过是随便敲敲键盘的事儿),网络上给的解决思路,基本上可以分为两个方向:

     一、使用Movie类,将Gif当成视频来播放。 经验证之后发现这种方法并不靠谱,播放的Gif不是花屏就是完全黑屏,而且另外一个缺点是可操作性不强,比如就没有办法把它嵌在TextView中。因此,不推荐用此方法,各位所有为此困扰的建议果断抛弃这种思路。

     二、将Gif文件 分解成多帧图片,然后由一个线程控制ImageView或者ImageSpan按照一定的时间间隔循环加载这几帧图片。

          而对于如何将Gif图片分解成多帧图片又有两种思路:一个是人工采用一个软件将gif图片分解成多个帧,然后把这每一帧都放进资源文件夹中,然后按照上面的方法进行加载,这种方法虽然看起来很笨,但是效果最流畅,我估计较早版本的手机QQ可能这样干过==    另外一种思路就是采用工具类进行即时解码,这种方法看起来比较高端,但对内存资源的消耗比较多,还有一个关键的问题是现在很难找到一个完美的工具类可以对Gif图片有较好的解码,我想腾讯肯定会有,但是不见得会开源..现在code.google.com上一个gifView.jar的工具包,有兴趣可以去网上搜一下,这个工具包里面对于gif的软解码还是比较全,当然也不完美。

     在本项目中采用的也是第二种思路,即采用一个工具类GifOpenHelper.java对gif进行解码,将生成的一组Bitmap对象存储在一个ArrayList中,然后由线程控制加载。这里首先声明这个工具类不是我原创的,也有一些缺陷,首先给出这个类:

package com.example.textactivity; import java.io.InputStream; import java.util.Vector; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; //Handler for read & extract Bitmap from *.gif public class GifOpenHelper { // to store *.gif data, Bitmap & delay class GifFrame { // to access image & delay w/o interface public Bitmap image; public int delay; public GifFrame(Bitmap im, int del) { image = im; delay = del; } } // to define some error type public static final int STATUS_OK = 0; public static final int STATUS_FORMAT_ERROR = 1; public static final int STATUS_OPEN_ERROR = 2; protected int status; protected InputStream in; protected int width; // full image width protected int height; // full image height protected boolean gctFlag; // global color table used protected int gctSize; // size of global color table protected int loopCount = 1; // iterations; 0 = repeat forever protected int[] gct; // global color table protected int[] lct; // local color table protected int[] act; // active color table protected int bgIndex; // background color index protected int bgColor; // background color protected int lastBgColor; // previous bg color protected int pixelAspect; // pixel aspect ratio protected boolean lctFlag; // local color table flag protected boolean interlace; // interlace flag protected int lctSize; // local color table size protected int ix, iy, iw, ih; // current image rectangle protected int lrx, lry, lrw, lrh; protected Bitmap image; // current frame protected Bitmap lastImage; // previous frame protected int frameindex = 0; public int getFrameindex() { return frameindex; } public void setFrameindex(int frameindex) { this.frameindex = frameindex; if (frameindex > frames.size() - 1) { frameindex = 0; } //设置循环播放 } protected byte[] block = new byte[256]; // current data block protected int blockSize = 0; // block size // last graphic control extension info protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev protected int lastDispose = 0; protected boolean transparency = false; // use transparent color protected int delay = 0; // delay in milliseconds protected int transIndex; // transparent color index protected static final int MaxStackSize = 4096; // max decoder pixel stack size // LZW decoder working arrays protected short[] prefix; protected byte[] suffix; protected byte[] pixelStack; protected byte[] pixels; protected Vector frames; // frames read from current file protected int frameCount; // to get its Width / Height public int getWidth() { return width; } public int getHeigh() { return height; } /** * Gets display duration for specified frame. * * @param n * int index of frame * @return delay in milliseconds */ public int getDelay(int n) { delay = -1; if ((n >= 0) && (n > 2; // disposal method if (dispose == 0) { dispose = 1; // elect to keep old image if discretionary } transparency = (packed & 1) != 0; delay = readShort() * 10; // delay in milliseconds transIndex = read(); // transparent color index read(); // block terminator } // to get Stream - Head protected void readHeader() { String id = ""; for (int i = 0; i < 6; i++) { id += (char) read(); } if (!id.startsWith("GIF")) { status = STATUS_FORMAT_ERROR; return; } readLSD(); if (gctFlag && !err()) { gct = readColorTable(gctSize); bgColor = gct[bgIndex]; } } protected void readImage() { // offset of X ix = readShort(); // (sub)image position & size // offset of Y iy = readShort(); // width of bitmap iw = readShort(); // height of bitmap ih = readShort(); // Local Color Table Flag int packed = read(); lctFlag = (packed & 0x80) != 0; // 1 - local color table flag // Interlace Flag, to array with interwoven if ENABLE, with order // otherwise interlace = (packed & 0x40) != 0; // 2 - interlace flag // 3 - sort flag // 4-5 - reserved lctSize = 2


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有