热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android之文本前面或后面多标签

之前写过一篇图文混排的,算法就是通过计算文本宽及行数,在换行的时候截取文本剩余的部分显示在图片下边,代码下载:demo今天这边是工作共常用到的,标签在前或在最后显示,比如帖子前边显示

之前写过一篇图文混排的,算法就是通过计算文本宽及行数,在换行的时候截取文本剩余的部分显示在图片下边,

代码下载:demo


今天这边是工作共常用到的,标签在前或在最后显示,比如帖子前边显示多个标签表示精华帖、优秀帖、解决标签等;其实主要是重写DynamicDrawableSpan,以及通过设置SpanableStringBuilder,来显示的。

先上图


代码如下:

主要是将普通文本替换成图片文本之后(spannaableString)追加到文本后边

/**
* 添加标签
*
* @param tagIconPosition 将标签放在文本的前面或者后边
* @param tagDrawableIdList 本地标签的drawableId集合
*/
private CharSequence addTagText(final int tagIconPosition, final List tagDrawableIdList, CharSequence emojiText) {
if (tagDrawableIdList == null || tagDrawableIdList.size() == 0) {
return emojiText;
}
setText(emojiText);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("");

for (int i = 0; i spannableStringBuilder.append("t ");
}

for (int i = 0; i int resourceId = tagDrawableIdList.get(i);
TagSpan tagSpanned = new TagSpan(context, resourceId, (int) getTextSize(), TagSpan.ALIGN_BASELINE, (int) getTextSize());
spannableStringBuilder.setSpan(tagSpanned, i * 2, i * 2 + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
CharSequence sepText = getText();
if (tagIcOnPosition== START) {//icon显示在前面
spannableStringBuilder.append(sepText);
} else {
spannableStringBuilder.insert(0, sepText);
}
// setText(spannableStringBuilder);//最后设置
return spannableStringBuilder;
}


重写DynamicDrawableSpan类,设置tag的位置,主要是因为用原生的Span会有边界错位的问题,所以要重写onDraw()

代码如下:也不复杂,计算方式自己根据需要调整

public Drawable getDrawable() {
if (mDrawable == null) {
try {
mDrawable = mContext.getResources().getDrawable(mResourceId);
mHeight = mSize;
mWidth = mHeight * mDrawable.getIntrinsicWidth() / mDrawable.getIntrinsicHeight();
mTop = (mTextSize - mHeight) / 2;
// 设置边界还是会导致错位
mDrawable.setBounds(0, mTop, mWidth, mTop + mHeight);
} catch (Exception e) {
// swallow
}
}
return mDrawable;
}

@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
//super.draw(canvas, text, start, end, x, top, y, bottom, paint);
Drawable b = getCachedDrawable();
canvas.save();

int transY = bottom - b.getBounds().bottom;
if (mVerticalAlignment == ALIGN_BASELINE) {// 绘制图片的位置
transY = top + ((bottom - top) / 2) - ((b.getBounds().bottom - b.getBounds().top) / 2) - mTop;
}
// 由于图片会错位,所以要移动这个画布
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}





现在说另一种实现方式:不过就是因为这种实现方式有错位问题,才使用方式一的,但是有些情况不需要自定义DynamicDrawableSpan就可以插入文本的,多学点无坏处吧,一并写下来说不定以后对自己有帮助

实现方式是通过Html.fromHtml( text,imageGetter);实现的;

代码如下:

1 、实现一个html转化时需要的imageGetter,主要用于识别html 带有的标签

/**
* 注:在异步线程中:先将文本表情转换成charsequence,然后加载icon,再者将icon放在文本表情的前或后,最后通过handler在主线程中设置textview 下午8:47:02 Spanned
*/
private Spanned convertTagToIconSpanned(CharSequence emojiText, int tagIconPosition, List tagDrawablIds) {
StringBuilder temp = new StringBuilder();
for (int i : tagDrawablIds) {//先将drawId转成html标签,
temp.append(" ");
}

Spanned tagSpanned = Html.fromHtml(temp.toString(), getImageGetterInstance(), null);
if (tagIcOnPosition== START) {// 本地图片放在文本前边
SpannableStringBuilder span = new SpannableStringBuilder(tagSpanned);
span.append(emojiText);
return span;
} else if (tagIcOnPosition== END) {// 本地图片放在文本后边
SpannableStringBuilder span = new SpannableStringBuilder(emojiText);
span.append(tagSpanned);
return span;
}
return new SpannableStringBuilder(emojiText);
}

2、获取标签的图片

/**
* ImageGetter用于text图文混排
*
* @return
*/
public ImageGetter getImageGetterInstance() {
ImageGetter imgGetter = new ImageGetter() {
@Override
public Drawable getDrawable(String source) {// 可用于加载本地图片和网络图片,source就是标签设置的 src的值
int fOntH= (int) (getTextSize());
int id = Integer.parseInt(source);

Drawable d = drawableMap.get(id);

if (d == null) {
d = getResources().getDrawable(id);
drawableMap.put(id, d);
}

int height = fontH;
int width = (int) ((float) d.getIntrinsicWidth() / (float) d.getIntrinsicHeight()) * fontH;
if (width == 0) {
width = d.getIntrinsicWidth();
}

d.setBounds(0, 0, width, height);

return d;
}
};
return imgGetter;
}

3,通过html转化成 Spanned ;用于setText(),就完成设置了

Spanned tagSpanned = Html.fromHtml(temp.toString(), getImageGetterInstance(), null);

希望对你有一点帮助

多标签Demo



推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
我本僐悢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有