文章目录

  • TextView文本尾部添加标签,支持自动换行
    • 需求
    • 使用SpannableStringBuilder + ImageSpan实现
    • 代码实现
    • 参考

TextView文本尾部添加标签,支持自动换行

需求

开发过程中我们经常会遇到文字尾部添加标签的需求,看是很简单,其实蛮难做的。比如我们的设计稿如下:

打眼一看,一个水平方向线性布局就解决了,内部写两个TextView就行。

<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:padding="20dp"><TextViewandroid:id="@+id/tv3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="天行健,君子以自强不息;"android:textColor="#000"android:textSize="15sp" /><TextViewandroid:id="@+id/tv4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/room_member_role_bg"android:paddingLeft="6dp"android:paddingRight="6dp"android:text="王蛋蛋的芭比"android:textColor="#000"android:textSize="15sp" /></LinearLayout>

emmmmm,但是,要是文字是多行的呢,我们的标签还能顺利的放在后面么?

如果第一行文本过长,我们就会得到下面的结果:
尾部标签显示不全:

或者如下,尾部标签直接不显示。

如果文字最后一行的剩余空间放不下我们的尾部标签,比较通用的做法是让标签换行。

我们想要的是这样的:

接下来我们一步步实现这个需求。

使用SpannableStringBuilder + ImageSpan实现

使用过SpannableStringBuilder的同学都惊叹于它的强大,通过SpannableStringBuilder#setSpan()我们可以给TextView的文本设置独特的样式,比如加粗、斜体、字体大小、字体颜色、背景颜色、图片、删除线、下划线、点击事件等等。

我们这里也使用SpannableStringBuilder + 特定Span的方式来实现。

我们的尾部标签实质上是给特定文本添加一个drawable背景,经过调研发现,虽然我们可以通过ReplacementSpan等方式给文字绘制drawable背景,但是背景上方的文字却不显示,这个方案就暂时夭折了。

回过头来,我们发现SpannableStringBuilder + ImageSpan可以实现将图片自动换行,并且如果剩余空间不足时图片会自动换行,如下所示:

从第二个TextView可以看出,当前行的剩余空间不够放置ImageSpan图片时,会自动换行。这样就解决了我们的自动换行的问题。

我们接下来看下ImageSpan的构造方法,会发现它不仅支持Drawable,还支持Bitmap对象,具体如下:

我们还知道,View有个getDrawingCache()方法,它可以生成当前View的Bitmap缓存。

此时我们的实现思路可以串起来了,具体如下图:

代码实现

具体分为四步:
①创建TextView对象,设置drawable背景,设置字体样式,设置间距,设置文本等
②将View生成Bitmap对象
③根据Bitmap对象生成ImageSpan对象
④将ImageSpan对象设置到SpannableStringBuilder的对应位置

具体代码如下:注释写的很清楚,这里就不再赘述。

private void addTagToTextView(TextView target, String title, String tag) {if (TextUtils.isEmpty(title)) {title = "";}String content = title + tag;/*** 创建TextView对象,设置drawable背景,设置字体样式,设置间距,设置文本等* 这里我们为了给TextView设置margin,给其添加了一个父容器LinearLayout。不过他俩都只是new出来的,不会添加进任何布局*/LinearLayout layout = new LinearLayout(this);TextView textView = new TextView(this);textView.setText(tag);textView.setBackground(getResources().getDrawable(R.drawable.room_member_role_bg));textView.setTextSize(12);textView.setTextColor(Color.parseColor("#FDA413"));textView.setIncludeFontPadding(false);textView.setPadding(ScreenUtils.dip2px(this, 6), 0,ScreenUtils.dip2px(this, 6), 0);textView.setHeight(ScreenUtils.dip2px(this, 17));textView.setGravity(Gravity.CENTER_VERTICAL);LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);// 设置左间距layoutParams.leftMargin = ScreenUtils.dip2px(this, 6);// 设置下间距,简单解决ImageSpan和文本竖直方向对齐的问题layoutParams.bottomMargin = ScreenUtils.dip2px(this, 3);layout.addView(textView, layoutParams);/*** 第二步,测量,绘制layout,生成对应的bitmap对象*/layout.setDrawingCacheEnabled(true);layout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));// 给上方设置的margin留出空间layout.layout(0, 0, textView.getMeasuredWidth() + ScreenUtils.dip2px(this, (6 + 3)), textView.getMeasuredHeight());// 获取bitmap对象Bitmap bitmap = Bitmap.createBitmap(layout.getDrawingCache());//千万别忘最后一步layout.destroyDrawingCache();/*** 第三步,通过bitmap生成我们需要的ImageSpan对象*/ImageSpan imageSpan = new ImageSpan(this, bitmap);/*** 第四步将ImageSpan对象设置到SpannableStringBuilder的对应位置*/SpannableStringBuilder ssb = new SpannableStringBuilder(content);//将尾部tag字符用ImageSpan替换ssb.setSpan(imageSpan, title.length(), content.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);target.setText(ssb);
}

项目地址:Android_Base_Demo

具体代码请看:SpannableStringBuilderActivity

页面入口展示:

当然了,实现这种需求的方式有很多种,这里的这种方式比较取巧。大家如果有好的实现方式,还望不吝赐教,比心。

参考

Textview转化成Bitmap对象

TextView文本尾部添加标签,支持自动换行相关推荐

  1. 自定义View(四) ViewGroup 动态添加变长Tag标签 支持自动换行

    欲实现如下效果: 思路很简单就2步: 1.测量出ViewGroup的大小 2.找出子View的位置 若要实现动态添加标签view,就要实现ViewGroup的onMeasure().onLayout( ...

  2. android浮动文本,android 添加浮动标签在textView最尾端,自动换行

    1.文章背景 最近在做一个需求,效果图如下:先上张图 image 就是动态根据textView文本,追随一个标签在 最后面~ 其实代码也很简单,就是动态计算textView文本的宽度 和 标签的宽度, ...

  3. TextView显示html信息、在文本下面添加下划线、中划线、设置图片

    1,在文本下面添加下划线 tv.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); 2,在文本设置中划线并加清晰 tv.getPaint().setFlag ...

  4. 添加议题模块html,WordPress 技巧:为评论模块增加更多 HTML 标签支持

    WordPress 原生的评论模块内容,支持使用 HTML 标签来增强评论内容的格式和效果.但是这肯定会带来一些安全隐患,特别是评论这种随便一个浏览者都可以提交数据的地方,容易产生跨站攻击(XSS), ...

  5. WordPress 多媒体库添加分类和标签支持

    https://www.xhsay.com/wordpress-attachment-taxonomies.html 时不时看到有朋友说 WordPress 这么强大的系统,怎么多媒体附件都不支持分类 ...

  6. 使用控件设计窗体 上 布局主窗体 添加标签与文本框控件

    使用控件设计窗体 上 布局主窗体 添加标签与文本框控件 项目目标 所需控件 窗体基本设置 新建窗体 设置背景图片 设置平铺模式 设置icon 设置文字 修改名称 直接修改类名 标签控件与文本框控件 标 ...

  7. jsf用于页面判断的标签_JSF –在JSF视图页面中添加标签,图像,按钮和文本字段

    jsf用于页面判断的标签 There are various UI components that JSF framework includes by default. Let us see some ...

  8. c语言在文本每一行末尾追加字符串,c语言在末尾添加 C语言 在链表尾部添加节点...

    怎么用C语言在一个文件后面添加内容 怎么用C语言在一个文件后面添加内容 使用fopen函数打开文件,用fseek函数将文件位置调整到文件末尾,然后用fwrite函数写入数据即可.下面的示例代码,向1. ...

  9. Android 应用开发(40)---TextView(文本框)详解

    TextView(文本框)详解 1.基础属性详解: 通过下面这个简单的界面,我们来了解几个最基本的属性: 布局代码: <RelativeLayout xmlns:android="ht ...

最新文章

  1. python简介、安装及基本设置
  2. 路由及iptables学习笔记
  3. vue 数组中嵌套数组_vue+element-ui表单校验之数组多层嵌套
  4. php获得昨天零时的时间戳,php 获取时间今天明天昨天时间戳
  5. Golang并发:再也不愁选channel还是选锁
  6. JavaScript的DOM编程--01--js代码的写入位置
  7. 0基础学python有多难-0基础学Python有多难?
  8. ios中UIView和CALayer关系
  9. c++ 读文件_C语言文件操作大全
  10. java显示系统当前时间_Java获取系统当前时间
  11. 连续发送(刷屏)器(适用于Dev-C++ 5.11版本)
  12. STC12C5A60S2-定时器+数码管
  13. sodility文档--modifier函数修改器
  14. poi导出excel文件加密处理
  15. R语言异常值处理方法总结
  16. 达梦数据库-部署及日常工具使用
  17. [生存志] 第22节 历代大事件概览 五代十国
  18. 手机锂电池规格及充电曲线
  19. YOLO工程代码如何在windows上配置和运行!window上YOLO训练样本的制作
  20. oracle中去掉回车、Tab、制表、空格等特殊符号

热门文章

  1. 用xpath爬取豆瓣
  2. 记一次HDFS空间清理:Non DFS Used
  3. iMeta | 第1卷第3期来自8个国家的14篇文章正式发布(2022.9)
  4. djangoday02
  5. C++编译器无法捕捉到的8种错误
  6. STM32外扩SRAM芯片IS62wv51216兼容替换
  7. MyCat入门篇-什么是MyCat
  8. Pytorch之经典神经网络CNN(七) —— GoogLeNet(InceptionV1)(Bottleneck)(全局平均池化GAP)(1*1卷积)(多尺度)(flower花卉数据集)
  9. 软件保护系统Themida是否需要Internet才能工作?
  10. OSGI企业应用开发(十五)基于Spring、Mybatis、Spring MVC实现一个登录应用