android实现gif图与文字混排

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

  在github上找到了这样一种方法。Github地址https://github.com/TracyZhangLei/android-gif-demo

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

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

  convertNormalStringToSpannableString方法的返回值是SpannableString

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

  TextView通经常使用来显示普通文本,可是有时候须要对当中某些文本进行样式、事件方面的设置。Android系统通过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<AnimatedImageSpan> localImageSpanRef = new WeakReference<AnimatedImageSpan>(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师在线互动

作者:杰瑞教育

出处:http://blog.csdn.net/jerehedu/

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

时间: 2024-08-15 09:02:38

android实现gif图与文字混排的相关文章

Android 自绘TextView解决提前换行问题,支持图文混排

先看下效果图: 上面是MTextView,下面是默认的TextView. 一.原因 用最简单的全英文句子为例,如果有一个很长的单词,这一行剩余的空间显示不下了,那么规则就是不打断单词,而是把整个单词丢到下一行开始显示.这样本来没有错.一是咱们中国人都是方块字,怎么都放得下,不存在英文的这个问题.所以不习惯那个排版.二是如果TextView里面有图片,如图,不知道判断单词的代码是怎么弄得,总之它觉得最后一个啦字和后面的一串表情应该是一个整体,不能分开,就一起丢到第二行了,也就造成了这种难看的排版.

Android 实现文字与图片的混排

在我们的项目中,经常会碰到图片与文字混排的问题.解决这类问题的方法有很多,本文给出的方法不是唯一的,只有根据实际场景才能找到更适合的方法. 本文主要通过xml布局来实现图片与文字的混排(水平排列). 1.利用TextView实现图片与文字混排, android:drawableBottom在text的下方输出一个drawable,如图片. 如果指定一个颜色的话会把text的背景设为该颜色,并且同时和background使用时覆盖后者. android:drawableLeft在text的左边输出

Android Json数据的解析+ListView图文混排+缓存算法Lrucache 仿知乎

前几天心血来潮,打算根据看知乎的API自己做一个小知乎,定制的过程遇到ListView的优化问题及图片未缓存重加载等等许多问题,解决了以后打算和博友分享一下. 接口数据:http://api.kanzhihu.com/getpostanswers/20150925/archive 首先,Json数据太常用,相信每一位开发者Json的解析都是必备的.我们要准备以下知识: JavaBean,枚举你需要的元素,用来存储数据. 异步加载网络内容的必备途径,多线程加载+AsyncTask两种方式. Jso

Android图文混排(一)-实现EditText图文混合插入上传

前段时间做了一个Android会议管理系统,项目需求涉及到EditText的图文混排,如图: 在上图的"会议详情"中,需要支持文本和图片的混合插入,下图演示输入的示例: 当会议创建完成以后,保存数据到服务器,然后查看刚刚创建好的会议,如图: 一.明确需求 首先,点击"会议详情"文本框中,正常输入文本,然后点击左下角的图片图标,进入系统的相册用来选择一张图片并插入到文本框中,你还可以将光标停留在任意的文字中间,完成图片的插入,回退建即可以逐个删除文字,也可以删除图片.

android:如何在TextView实现图文混排

我们通常在TextView文本中设置文字.可是如何设置图文混排呢? 我就在这里写一个例子 .我们需要用到一点简单的HTML知识 在TextView中预订了一些类似HTML的标签,通过标签可以使TextView控件显示不同颜色,大小,字体的文字 <font>:设置颜色和字体 <big>:设置大号 <small>:设置小号 <i>\<b>:斜体.粗体 <a>:链接地址 <img>:插入图片 在drawable中存入我们的图片.

android 你所不知道的类SpannableStringBuilder的总结--实现图文混排,查看更多,下划线等等

今天无意中看到的一个类SpannableStringBuilder,查了下感觉很牛叉: 1.看下实现的效果 第一种 引用自:使用android SpannableStringBuilder实现图文混排,查看更多 第二种 实现的代码见   使用的模板 2.简单的使用模板: 引用自  http://blog.it985.com/14433.html public class MainActivity extends Activity implements OnClickListener { priv

Android图文混排-实现EditText图文混合插入上传

前段时间做了一个Android会议管理系统,项目需求涉及到EditText的图文混排,如图: 在上图的"会议详情"中.须要支持文本和图片的混合插入,下图演示输入的演示样例: 当会议创建完毕以后,保存数据到server.然后查看刚刚创建好的会议.如图: 一.明白需求 首先.点击"会议详情"文本框中,正常输入文本,然后点击左下角的图片图标.进入系统的相冊用来选择一张图片并插入到文本框中,你还能够将光标停留在随意的文字中间,完毕图片的插入.回退建即能够逐个删除文字,也能够

使用android SpannableStringBuilder实现图文混排,查看更多

项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的省略号后面添加图片. 直接上代码吧,代码注释很多,慢慢研究 private void toggleEllipsize(final TextView tv,final String desc){ if(desc == null){ return; } tv.getViewTreeObserver().

Android 图文混排 通过webview实现并实现点击图片

在一个开源项目看到是用的webview 实现的 1. 这是在asset中的一个模板html <html> <head> <title>News Detail</title> <meta name="viewport" content="width=device-width, minimum-scale=0.5, initial-scale=1.2, maximum-scale=2.0, user-scalable=1&qu