TextView 悬挂缩进实现及解析
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/tv_indent"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</LinearLayout>
代码:
- autoSplitText(tv,indent):该方法用来切割字符串,在需要换行的文本处添加换行符和缩进空格。
private String autoSplitText(final TextView tv, final String indent) {//此处拿到得还是一串长文本final String rawText = tv.getText().toString(); //原始文本final Paint tvPaint = tv.getPaint(); //paint,包含字体等信息final float tvWidth = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight(); //控件本身宽度//将缩进转换成空格String indentSpace = "";float indentWidth = 0;if (!TextUtils.isEmpty(indent)) {float rawIndentWidth = tvPaint.measureText(indent); //获取缩进的宽度if (rawIndentWidth < tvWidth) { //如果缩进宽度比控件本身宽度小的话while ((indentWidth = tvPaint.measureText(indentSpace)) < rawIndentWidth) {//将缩进的宽度转变为空格的形式表示出来indentSpace += " ";}//减去一个空格宽度indentSpace = indentSpace.substring(0, indentSpace.length() - 1);}}//将原始文本按行拆分// \r 光标重新回到本行开头// \n 光标往下一行String[] rawTextLines = rawText.replaceAll("\r", "").split("\n");StringBuilder sbNewText = new StringBuilder();for (String rawTextLine : rawTextLines) {if (tvPaint.measureText(rawTextLine) <= tvWidth) {//如果整行宽度在控件可用宽度之内,就不处理了sbNewText.append(rawTextLine);} else {//如果整行宽度超过控件可用宽度,则按字符测量,在超过可用宽度的前一个字符处手动换行float lineWidth = 0;//记录文字行宽for (int cnt = 0; cnt != rawTextLine.length(); ++cnt) {char ch = rawTextLine.charAt(cnt);if (lineWidth < 0.1f && cnt != 0) {//当lineWidth宽度等与0并且cnt不等于0时候,可以确认是在第二行,此时在行头加上缩进。sbNewText.append(indentSpace);lineWidth += indentWidth;}lineWidth += tvPaint.measureText(String.valueOf(ch));if (lineWidth <= tvWidth) {//文字行宽小于控件行宽,将文字添加进StringBuilder中。sbNewText.append(ch);} else {//如果文字行宽大于控件行宽,加入换行符号。清空文字宽度,cnt 减 1后再重新计算。//走到这一步之后会从for循环开头走,在下一行加缩进。sbNewText.append("\n");lineWidth = 0;--cnt;}}}sbNewText.append("\n");}//把结尾多余的\n去掉if (!rawText.endsWith("\n")) {sbNewText.deleteCharAt(sbNewText.length() - 1);}return sbNewText.toString();}
}
- 使用:
- 注册一个观察者来监听视图,当视图树的布局发生改变或者View在视图树的可见状态发生改变时会调用的接口ViewTreeObserver.OnGlobalLayoutListener()。
- 并且在ViewTreeObserver.OnGlobalLayoutListener()回调函数中设置SpannableStringBuilder点击也不会有冲突。
final TextView tvIndent = (TextView) findViewById(R.id.tv_indent);
String upgradeContent = "1,Google LLC 是一家美国跨国科技公司,专门从事互联网相关服务和产品,包括在线广告技术,搜索引擎,云计算,软件和硬件。\n2,Google由Larry Page和Sergey Brin于1998年创立,当时他们是博士。学生在斯坦福大学在加州。\n3,他们共同拥有约14%的股份,并通过超级投票控制56%的股东投票权股票。\n4,他们于1998年9月4日将Google合并为一家私营公司。\n5,2004年8月19日首次公开募股(IPO),谷歌搬到位于加利福尼亚州山景城的总部,绰号为Googleplex。\n6,2015年8月,谷歌宣布计划重组其作为一家名为Alphabet Inc.的企业集团的各种利益。谷歌是Alphabet的主要子公司,并将继续成为Alphabet互联网利益的保护伞公司。\n7,Sundar Pichai被任命为Google首席执行官,取代Larry Page成为Alphabet的首席执行官。";
tvIndent.setText(upgradeContent);
tvIndent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)@Overridepublic void onGlobalLayout() {//回调之后取消监听,防止回调被来回调取。tvIndent.getViewTreeObserver().removeOnGlobalLayoutListener(this);String indentTextDesc = autoSplitText(tvIndent, "1,");String targetClick = "搜索引擎";SpannableStringBuilder contentSpannableBuilder = new SpannableStringBuilder(indentTextDesc);contentSpannableBuilder.setSpan(new ClickableSpan() {@Overridepublic void onClick(View widget) {Toast.makeText(MainActivity.this, "Toast 被点击", Toast.LENGTH_LONG).show();}@Overridepublic void updateDrawState(TextPaint ds) {ds.setUnderlineText(true);ds.setColor(Color.parseColor("#067ce4"));ds.setFakeBoldText(true);}}, indentTextDesc.indexOf(targetClick), indentTextDesc.indexOf(targetClick) + targetClick.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);tvIndent.setMovementMethod(LinkMovementMethod.getInstance());tvIndent.setText(contentSpannableBuilder);}
});
效果:
TextView 悬挂缩进实现及解析相关推荐
- Android Textview缩进之悬挂缩进
很多地方都需要用到类似这样的悬挂缩进,排版看起来比较整齐.代码实现起来也很简单,几行就搞定了. String str = "1. Because of the protocol implem ...
- Endnote X9.1 参考文献悬挂缩进
Endnote X9.1 参考文献悬挂缩进 原来参考文献:(style) 修改后参考文献:(style) 具体操作方法(Method): 在word中插入一篇引文:打开EndnoteX9.1软件,选中 ...
- CSS实现首行缩进和悬挂缩进
首行缩进 text-indent控制首行缩进,后加缩进长度,数值可正可负,单位可以是em,百分比,或者绝对单位.以数值2为例,取值可以是: 1. 2em 参见em,相对长度单位,为父元素文本字体尺寸的 ...
- Latex---局部调大字体--下划线--首行缩进--悬挂缩进
1 调整字体大小 \tiny \scriptsize \footnotesize \small \normalsize \large \Large \LARGE \huge \Huge 2 下划线 \ ...
- css div 悬挂缩进_CSS中的经典字体效果:悬挂缩进
css div 悬挂缩进 A hanging indent, or hanging paragraph, is a paragraph in which the opening line is lef ...
- 如何在Microsoft PowerPoint中创建或删除悬挂缩进
A hanging indent (often called a negative indent) positions the first line of a paragraph a predeter ...
- 调整字符宽度后,首行缩进或悬挂缩进的排版“乱了”
调整字符宽度后,可能会出现段落首行缩进和悬挂缩进的排版 "乱了"的现象.本文针对该现象的出现原因进行分析,并整理了解决办法. 1. 现象 (1)未调整字符宽度时,对段落中文本设置悬 ...
- EndNote文献悬挂缩进的设置方法及设置参考文献序号后面空格长度
一.EndNote文献悬挂缩进的设置方法 写论文时使用EndNote来插入和管理参考文献是一种非常方便的方法,但有时不同的杂志要求插入的文献要求第二行缩进格式,或者不缩进. 1.在EndNote中Ed ...
- 20210712 专利自动编号,悬挂缩进
把悬挂缩进改下就OK
- 首行缩进和悬挂缩进的区别
首行缩进和悬挂缩进是常见的段落缩进方式,用于调整段落的排版样式.它们可以在文本处理软件中应用于段落或选定的文本部分. 首行缩进:首行缩进是指将段落的第一行向内缩进一定的距离,以使段落的其余行保持靠近页 ...
最新文章
- CoreSight介绍篇
- 风格迁移应用_[风格迁移][超分][ECCV2016]Perceptual Losses for Real...
- git 改了一段代码不想要了_初识Git
- 挑选SaaS企业需要注意十要素
- 【10.20校内测试】【小模拟】【无向图建树判奇偶环】【树上差分】
- C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)
- 团队作业8—团队项目用户验收评审
- Git学习文档之一 学习文档-合并分支
- Linux下C语言的调试器 Gdb
- php excel数据导出
- 大学物理复盘 | 简明大学物理学第一章——质点运动学思维导图梳理(复习专用)
- 如何备份linux磁盘空间,请问怎么备份整个硬盘又快又省空间?
- 数电Day06:主从触发器和边沿触发器,触发器的逻辑符号,时序波形
- matlab中imshow函数输出图像全白全黑问题
- js版的倒计时(月-日-时-分-秒-毫秒)
- 【Web前端初学笔记】②HTML基本结构标签,VSCode工具创建页面,网页开发工具
- PARI/GP 语言:从入门到实现大素数判定与大数分解
- web网站访问计数器
- 数字2019的分解问题
- 洛谷 P1309 瑞士轮 归并
热门文章
- 深圳海伊视讯布控球成功对接海康萤石云平台安装调式
- Linux 管道 管道命令 命名管道
- android极光推送sequence,极光推送接入
- 【数据库】数据、数据库、数据库管理系统、数据库系统
- The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.
- java关于文件上传和下载,保存到后台并修改名字。
- Lab4 Architecture Lab
- 自然数e的故事(转)
- android 仿ios数字密码解锁界面
- 那些堪比照片质感的PhotoRealistic Style Transfer系列