行内标签的实现

作者: zhuguohui | 来源:发表于2017-01-19 11:29 被阅读90次

    序言

    在最近的项目中需要实现行内标签,我原来觉得挺简单的后来,后来试了很多方式发现并没有那么简单。比如想到的几种实现方式和最终的效果如下图,本着辛苦我一个方便千万家的思想,我把我的TagUtil抽取出来了,并上传到GitHub上了。

    这里写图片描述

    实现思路

    1.首先需要一个tag的布局文件

    这里写图片描述

    2.手动的填充布局文件,生成一个TextView
    3.根据这个TextView获取它的截屏,生成一个Bitmap
    4.将bitmap设置到需要显示tag的TextView上,这和TextView中显示表情的原理是一样的。

    代码如下

    package com.trs.nxnews.news.util;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.text.SpannableString;
    import android.text.TextUtils;
    import android.text.style.ImageSpan;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.TextView;
    
    import com.trs.nxnews.R;
    
    import static android.text.Spanned.SPAN_INCLUSIVE_EXCLUSIVE;
    
    /**
     * Created by zhuguohui on 2016/12/12.
     */
    
    public class TagUtil {
        public static void setTag(String tag, TextView textView) {
            if (TextUtils.isEmpty(tag) || "无".equals(tag)) {
                return;
            }
            //填充tag布局
            TextView tv_tag = (TextView) LayoutInflater.from(textView.getContext()).inflate(R.layout.view_tag, null, true);
            tv_tag.setText(tag);
    
            //获取View的截图,用来当Tag图标
            Bitmap drawingCache = convertViewToBitmap(tv_tag);
    
            //将图片设置到TextView中
            BitmapDrawable bitmapDrawable = new BitmapDrawable(drawingCache);
            bitmapDrawable.setBounds(0, 0, drawingCache.getWidth(), drawingCache.getHeight());
            SpannableString spannableString = new SpannableString(tag + textView.getText());
            MyIm imageSpan = new MyIm(bitmapDrawable);
            spannableString.setSpan(imageSpan, 0, tag.length(), SPAN_INCLUSIVE_EXCLUSIVE);
            textView.setText(spannableString);
        }
    
        /**
         * 获取tag图标
         *
         * @param view
         * @return
         */
        public static Bitmap convertViewToBitmap(View view) {
            view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
            view.buildDrawingCache();
            Bitmap bitmap = view.getDrawingCache();
            return bitmap;
        }
    
        /**
         * 可以居中对齐的ImageSPan
         */
        public static class MyIm extends ImageSpan {
            public MyIm(Context arg0, int arg1) {
                super(arg0, arg1);
            }
    
            public MyIm(Drawable drawable) {
                super(drawable);
            }
    
            public int getSize(Paint paint, CharSequence text, int start, int end,
                               Paint.FontMetricsInt fm) {
                Drawable d = getDrawable();
                Rect rect = d.getBounds();
                if (fm != null) {
                    Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
                    int fontHeight = fmPaint.bottom - fmPaint.top;
                    int drHeight = rect.bottom - rect.top;
    
                    int top = drHeight / 2 - fontHeight / 4;
                    int bottom = drHeight / 2 + fontHeight / 4;
    
                    fm.ascent = -bottom;
                    fm.top = -bottom;
                    fm.bottom = top;
                    fm.descent = top;
                }
                //15为padding
                return rect.right + 15;
            }
    
            @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 = 0;
                transY = ((bottom - top) - b.getBounds().bottom) / 2 + top;
                canvas.translate(x, transY);
                b.draw(canvas);
                canvas.restore();
            }
        }
    }
    
    

    源码

    TAGDemo

    总结

    有一些事情并没有想象中那么简单,多积累一点一滴的技术,学会灵活运用技术,这样开发才会越来越简单,与君共勉。

    相关文章

      网友评论

        本文标题:行内标签的实现

        本文链接:https://www.haomeiwen.com/subject/mlkibttx.html