博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android实现gif图与文字混排
阅读量:6341 次
发布时间:2019-06-22

本文共 4369 字,大约阅读时间需要 14 分钟。

  我们在进行qq聊天的时候发送表情,但这些表情都是并非静态的,很多其它的是动态图,gif图,那么怎样在androidclient显示动态gif图呢。

  在github上找到了这样一种方法。Github地址

  因为我是截图,所以看不到动态效果。大家能够自己下载看一下。

  我们首先来看一下该开源项目的代码。该开源项目主要是通过自己定义一个Adapter-------chatAdapter,在ChatAdapter每一条的setText属性中使用了自己定义的方法convertNormalStringToSpannableString

  convertNormalStringToSpannableString方法的返回值是SpannableString

  我们首先来了解一下什么是SpannableString

  TextView通经常使用来显示普通文本,可是有时候须要对当中某些文本进行样式、事件方面的设置。系统通过SpannableString类来对指定文本进行相关处理。也就是说我们想要实现文字加动态表情的实现就要通过SpannableString这个类来实现。

 
private SpannableString convertNormalStringToSpannableString(String message , final TextView tv) {        SpannableString value = SpannableString.valueOf(message);        Matcher localMatcher = EMOTION_URL.matcher(value);        while (localMatcher.find()) {            String str2 = localMatcher.group(0);            int k = localMatcher.start();            int m = localMatcher.end();            if (m - k < 8) {                int face = fm.getFaceId(str2);                if(-1!=face){//wrapping with weakReference                    WeakReference
localImageSpanRef = new WeakReference
(new AnimatedImageSpan(new AnimatedGifDrawable(cxt.getResources().openRawResource(face), new AnimatedGifDrawable.UpdateListener() { @Override public void update() {//update the textview tv.postInvalidate(); } }))); value.setSpan(localImageSpanRef.get(), k, m, Spanned.SPAN_INCLUSIVE_INCLUSIVE); } } } return value; }

  首先将我们传入的message转化成SpannableString类,然后看一下传入的值是否符合我们一開始写好的正則表達式EMOTION_URL

 
private Pattern EMOTION_URL = Pattern.compile("\\[(\\S+?

)\\]");

  假设符合的话 我们取group(0)

  附:group是针对()来说的,group(0)就是指的整个串。group(1)指的是第一个括号中的东西,group(2)指的第二个括号中的东西。

  子表达式和起始位置和结束位置的差小于8,也就是符合我们的要求。调用FaceManager中的getFaceId方法

 
public int getFaceId(String faceStr){        if(mFaceMap.containsKey(faceStr)){            return mFaceMap.get(faceStr);        }        return -1;    }

  找到我们用Map进行存储的表情

  假设表情存在的话利用一个弱引用(WeakReference)把自己定义的AnimatedImageSpan进行处理,使AnimatedImageSpan不那么的消耗内存。在UpdateListener中利用postInvalidate刷新界面。最后把SpannableString的setSpan方法,三个參数各自是要放进去的span ,起始位置。结束位置,flag标志。

  关于flag:

  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE。 这是在 setSpan 时须要指定的 flag,它是用来标识在 Span 范围内的文本前后输入新的字符时是否把它们也应用这个效果。分别有 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包含)、 Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包含,后面不包含)、 Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包含,后面包含)、 Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包含)。

  最后将SpannableString返回,实现动态图文混排。

  关于自己定义的AnimatedImageSpan例如以下:

 
public class AnimatedImageSpan extends DynamicDrawableSpan {    private Drawable mDrawable;    public AnimatedImageSpan(Drawable d) {        super();        mDrawable = d;        // Use handler for 'ticks' to proceed to next frame         final Handler mHandler = new Handler();        mHandler.post(new Runnable() {            public void run() {                ((AnimatedGifDrawable)mDrawable).nextFrame();                // Set next with a delay depending on the duration for this frame                 mHandler.postDelayed(this, ((AnimatedGifDrawable)mDrawable).getFrameDuration());            }        });    }    @Override    public Drawable getDrawable() {        return ((AnimatedGifDrawable)mDrawable).getDrawable();    }    @Override    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {        Drawable d = getDrawable();        Rect rect = d.getBounds();        if (fm != null) {            fm.ascent = -rect.bottom;             fm.descent = 0;             fm.top = fm.ascent;            fm.bottom = 0;        }        return rect.right;    }    @Override    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {        Drawable b = getDrawable();        canvas.save();        int transY = bottom - b.getBounds().bottom;        if (mVerticalAlignment == ALIGN_BASELINE) {            transY -= paint.getFontMetricsInt().descent;        }        canvas.translate(x, transY);        b.draw(canvas);        canvas.restore();    }}

 

  假设大家有疑问。欢迎增加QQ群: (452379712)。与杰瑞教育高级project师在线互动

 

作者:
出处:
 
本文版权归和CSDN共同拥有,欢迎转载,但未经作者允许必须保留此段声明。且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

转载于:https://www.cnblogs.com/yutingliuyl/p/6953180.html

你可能感兴趣的文章
CentOS6 手动编译升级 gcc
查看>>
memcached的安装与开启脚本
查看>>
Linux与Window字符集~~伤不起的幽灵空白符
查看>>
zabbix 邮件报警 -- sendmail
查看>>
JavaScript异步编程
查看>>
tcpdump用法小记
查看>>
MySQL基础安全注意细节
查看>>
Oracle随机函数—dbms_random
查看>>
pvr 批量转换
查看>>
linux命令basename使用方法
查看>>
windows下开发库路径解决方案
查看>>
linux迁移mysql数据目录
查看>>
脚本源码安装LNMP
查看>>
Percona Server安装
查看>>
函数为左边表达式
查看>>
LoadRunner 12.0.2的安装
查看>>
const,static,extern简介(重要)
查看>>
读书杂谈一
查看>>
winform listbox 元素显示tooltrip
查看>>
cacti安装与配置
查看>>