给TextView文本加标签,小功能大秘密(1)

emmmmm,但是,要是文字是多行的呢,我们的标签还能顺利的放在后面么?如果第一行文本过长,我们就会得到下面的结果:尾部标签显示不全。

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

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

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

/   实现   /

=====================================================================

使用SpannableStringBuilder+ImageSpan实现使用过SpannableStringBuilder的同学都惊叹于它的强大,通过SpannableStringBuilder#setSpan()我们可以给TextView的文本设置独特的样式,比如加粗、斜体、字体大小、字体颜色、背景颜色、图片、删除线、下划线、点击事件等等。我们这里也使用SpannableStringBuilder+特定Span的方式来实现。我们的尾部标签实质上是给特定文本添加一个drawable背景,经过调研发现,虽然我们可以通过ReplacementSpan等方式给文字绘制drawable背景,但是背景上方的文字却不显示,这个方案就暂时夭折了。回过头来,我们发现SpannableStringBuilder+ImageSpan可以实现将图片自动换行,并且如果剩余空间不足时图片会自动换行,如下所示:

从第二个TextView可以看出,当前行的剩余空间不够放置ImageSpan图片时,会自动换行。这样就解决了我们的自动换行的问题。我们接下来看下ImageSpan的构造方法,会发现它不仅支持Drawable,还支持Bitmap对象,具体如下:

我们还知道,View有个getDrawingCache()方法,它可以生成当前View的Bitmap缓存。此时我们的实现思路可以串起来了,具体如下图:

/   代码实现   /

=======================================================================

具体分为四步:

  1. 创建TextView对象,设置drawable背景,设置字体样式,设置间距,设置文本等

  2. 将View生成Bitmap对象

  3. 根据Bitmap对象生成ImageSpan对象

  4. 将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);

}

尾声

一转眼时间真的过的飞快。我们各奔东西,也各自踏上了自己的旅途,但是即使多年不见,也因为这份情谊我们依旧如从前那般“亲密”。不忘初心方得始终。加油吧,程序员们,在我看来35岁,40岁从来不是危机,只要永远不要忘记自己为何踏上征程!

为了让更多在学习中或者最近要准备面试的朋友们看到这篇文章,希望你们能多多评论,点赞+转发!

再次感谢所有给我提供过题目的朋友们,感谢一路有你!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值