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

TextView显示丰富多彩的文字(二)——如何使用ParagraphStyle格式化段落

在上一篇博客TextView显示丰富多彩的文字(一)——如何使用CharacterStyle格式化字符中介绍了CharacterStyle的接口,并使用了Character的多个实现类

在上一篇博客TextView显示丰富多彩的文字(一)——如何使用CharacterStyle格式化字符中介绍了CharacterStyle的接口,并使用了Character的多个实现类介绍了一下文字改变效果。下面是Spannable的setSpan的API:
Spannable的setSpan方法其中可以看到第一个参数不止可以是CharacterStyle,还可以使ParagraphStyle、TextWatecher和SpanWatcher的子类。今天这篇博客主要介绍如何使用ParagraphStyle。

ParagraphStyle

ParagraphStyle是一个接口,实现该接口的类会在段落级别影响文本格式化。
ParagraphStyle的类结构
ParagraphStyle有很多实现类。下面是具体的层次图,查看文档可以知道,第二层的子类还都是接口,只有最底层的才是实现类。
ParagraphStyle的具体类结构
下面我们就以例子来说明具体每个格式的用法。

示例

首先先看一下没有添加任何效果的显示。为了让下面的示例能看出设置margin的区别,特地将TextView的背景设为绿色,没有padding。
没有设置ParagraphStyle的效果
下面是代码,就是简单的获取了TextView,然后用SpannableString转换了一下文本,再设置给了TextView。

            "连通东西部多条铁路干线的郑徐高铁将正式通车运营," +
"中国高铁网络再次得到完善,东中西部民众的高铁出行也" +
"更加便利。与此同时,今天开始,受郑徐高铁开通影响," +
"全国铁路再次迎来一次运行图大调整。";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paragraph);

mTextView = (TextView) findViewById(R.id.paragraph_tv);
SpannableString spannableString = new SpannableString(paragraph);
mTextView.setText(spannableString);
}" data-snippet-id="ext.dcec503fab055853a9d8ad9f686d0a3e" data-snippet-saved="false" data-codota-status="done"> private TextView mTextView;

private String paragraph = "中新网北京9月10日电 今天," +
"连通东西部多条铁路干线的郑徐高铁将正式通车运营," +
"中国高铁网络再次得到完善,东中西部民众的高铁出行也" +
"更加便利。与此同时,今天开始,受郑徐高铁开通影响," +
"全国铁路再次迎来一次运行图大调整。";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paragraph);

mTextView = (TextView) findViewById(R.id.paragraph_tv);
SpannableString spannableString = new SpannableString(paragraph);
mTextView.setText(spannableString);
}

LeadingMarginSpan

LeadingMarginSpan会影响段落的leading margin(我称它为领先margin)。同一个段落可以设置多个不同的leading margin。这些margin会叠加。如果段落是一个从右到左的,那么margin就会从右边开始计算。使用LeadingMarginSpan需要被添加到整个段落,即范围从第一个字符到最后一个字符。下面是实现该接口的类的例子。

LeadingMarginSpan.Standard

该类只会调整margin,而不会做任何渲染。可以用该类来实现段落的整体右移。先看该类的构造方法:

LeadingMarginSpan.Standard(int first, int rest)
LeadingMarginSpan.Standard(int every)
LeadingMarginSpan.Standard(Parcel src)

其中第三个是因为实现了Parcelable接口的缘故,暂不考虑。第一个构造方法有两个参数,其中第一个参数设置第一行的margin,第二个参数设置其余行的margin(==可以用该构造方法实现首行缩进的功能==)。第二个构造方法就是设置每一行的margin都一样。下面先看第二种构造方法的效果:

 //使用每行都一样的LeadingMarginSpan.Standard
LeadingMarginSpan.Standard standard = new LeadingMarginSpan.Standard(60);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果如下,就像TextView内部设置了leftPadding一样
Standard的用法,每行margin都一样
下面再看第一种构造方法的用法,实现首行缩进的功能。

 //使用首行缩进的LeadingMarginSpan.Standard
LeadingMarginSpan.Standard standard = new LeadingMarginSpan.Standard(60,20);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果如下:
这里写图片描述

BulletSpan

废话不多说,先看代码,再看效果。看了效果就会知道这个效果是怎样的了。

//使用默认的BulletSpan
BulletSpan bulletSpan = new BulletSpan();
spannableString.setSpan(bulletSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

使用默认的BulletSpan
上面是使用默认的BulletSpan,看了效果后,可以知道BulletSpan会在段落前加上个圆点。可以用于无序列表。BulletSpan有几个构造方法,如下:

BulletSpan()
BulletSpan(int gapWidth)
BulletSpan(int gapWidth, int color)
BulletSpan(Parcel src)

其中两个参数的gapWidth用于设置圆点和文字之间的距离,一个用于设置圆点颜色。下面将通过两个参数的构造方法构造BulletSpan,效果如下:
设置BulletSpan的间隔和圆点颜色
其中设置的间隔为50,颜色为红色,代码如下:

 //使用两个构造方法的BulletSpan
BulletSpan bulletSpan = new BulletSpan(50, Color.RED);
spannableString.setSpan(bulletSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
QuoteSpan

还是先看代码和效果

 //使用默认的QuoteSpan
QuoteSpan quoteSpan = new QuoteSpan();
spannableString.setSpan(quoteSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

QuoteSpan的默认效果
可以看到QuoteSpan的效果是在文本左边加上一条竖直的线,默认颜色为蓝色。下面尝试改变该颜色:

//使用带颜色的QuoteSpan
QuoteSpan quoteSpan = new QuoteSpan(Color.RED);
spannableString.setSpan(quoteSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果如下,竖直的线确实变成了红色
设置QuoteSpan的竖直线颜色

DrawableMarginSpan

DrawableMaiginSpan有两个构造方法。其中

DrawableMarginSpan(Drawable b)
DrawableMarginSpan(Drawable b, int pad)

我们这里展示第二个构造方法的的效果,其中第一个构造方法中pad参数为0。pad参数指图标和文字之间的距离。

DrawableMarginSpan drawableMarginSpan = new DrawableMarginSpan(getResources().getDrawable(R.mipmap.ic_launcher),30);
spannableString.setSpan(drawableMarginSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果如下:
DrawableMarginSpan的效果

IconMarginSpan

IconMarginSpan和DrawableSpan效果类似,只不过DrawableMarginSpan的构造方法中只能传入Drawable对象,而IconMarginSpan构造方法中只能传入Bitmap对象。下面是使用和效果:

//使用IconMarginSpan
IconMarginSpan icOnMarginSpan= new IconMarginSpan(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher), 30);
spannableString.setSpan(iconMarginSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

IconMarginSpan的效果
IconMarginSpan和DrawableMarginSpan的共同点还在于它们不仅仅实现了LeadingMarginSpan,还实现了LineHeightSpan。

AlignmentSpan

AlignmentSpan.Standard

还是先看用法和效果:

//使用AlignmentSpan.Standard居中显示
AlignmentSpan.Standard standard = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果:
AlignmentSpan.Standard居中显示的效果

//使用AlignmentSpan.Standard靠右显示
AlignmentSpan.Standard standard = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果:
AlignmentSpan.Standard靠右显示的效果

 //使用AlignmentSpan.Standard正常显示
AlignmentSpan.Standard standard = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果:
AlignmentSpan.Standard正常显示的效果
从上面可以看出来Alignment可以控制段落的对齐方式,就像Word中居中、靠右或靠左显示。

组合多个效果

下面使用了首行缩进的LeadingMarginSpan.Standard、BulletSpan和QuoteSpan,根据文档中会叠加这些效果。

//使用首行缩进的LeadingMarginSpan.Standard
LeadingMarginSpan.Standard standard = new LeadingMarginSpan.Standard(60,20);
spannableString.setSpan(standard, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//使用两个构造方法的BulletSpan
BulletSpan bulletSpan = new BulletSpan(50, Color.RED);
spannableString.setSpan(bulletSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
//使用带颜色的QuoteSpan
QuoteSpan quoteSpan = new QuoteSpan(Color.RED);
spannableString.setSpan(quoteSpan, 0, paragraph.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

效果如下:
组合多个效果
从上图可以看出,有了左边padding的效果、红色圆点和竖直红线的效果。

总结

以上基本就是常用的ParagraphStyle的实现类,有一点需要注意的是,上面的例子中文字都是都是从左到右的,如果设置了从右到左,那么margin就会在右边,而Alignment的NORMAL也就是靠右显示。其中SpannableString的用法,如果不了解的话,可以在第一篇TextView显示丰富多彩的文字(一)——如何使用CharacterStyle格式化字符博客中查看。


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
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社区 版权所有