行内标签的实现

序言

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

总结

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值