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

在上一篇博客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。

 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格式化字符博客中查看。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值