07.01 控件-TextView

2021/8/8 Android 开发基础

TextView 是向用户显示文本的控件。如果需要显示文本信息的话,那么默认的 TextView 控件将是一个很好的选择,同时它也有很多属性来控制文本的显示方式。

# 常用属性

  • id:为控件设置一个组件id,根据id,我们可以在Java代码中通过findViewById()的方法获取到该对象,然后进行相关属性的设置,又或者使用RelativeLayout时,参考组件用的也是id。
  • layout_width:组件的宽度,一般写:wrap_content或者match_parent(fill_parent),前者是控件显示的内容多大,控件就多大,而后者会填满该控件所在的父容器;当然也可以设置成特定的大小,如100dp大小。
  • layout_height:组件的高度,一般写:wrap_content或者match_parent(fill_parent),前者是控件显示的内容多大,控件就多大,而后者会填满该控件所在的父容器;当然也可以设置成特定的大小,如100dp大小。
  • gravity:设置控件中内容的对齐方向,可以设置centerlefttoprightbottom 等等属性来控制对齐的方向。
  • text:设置显示的文本内容,通用规范是把字符串写到string.xml文件中,然后通过@String/xxx取得对应的字符串内容的,非强制要求,而直接写文本的方式一般是用于测试使用。
  • textColor:设置字体颜色,通用规范是将颜色字符串写在colors.xml文件中,然后通过@color/xxx取得对应的颜色值的,非强制要求,而直接写颜色的方式一般是用于测试使用。
  • textStyle:设置字体风格,三个可选值:normal(正常),bold(加粗),italic(斜体)。
  • textSize:字体大小,常用的单位一般是用sp,也可以使用px,dp等单位。
  • background:控件的背景,可以理解为填充整个控件的背景,可以是图片或者color。
  • maxLength:限制显示的文本长度,超出部分不显示。
  • lines:设置文本的行数,设置两行就显示两行,即使第二行没有数据。
  • maxLines:设置文本的最大显示行数,与width或者layout_width结合使用,超出部分自动换行,超出行数将不显示。
  • singleLine:设置单行显示。当超过一行文本时,默认结尾...表示。
  • ellipsize:设置当文字过长时,该控件该如何显示。有如下值设置:”start” 省略号显示在开头;”end” 省略号显示在结尾;”middle” 省略号显示在中间;”marquee” 以跑马灯的方式显示(动画横向移动)。
  • lineSpacingExtra:设置行间距,如"3dp"。
  • lineSpacingMultiplier:设置行间距的倍数,如"1.2"倍。
  • typeface:设置字体,默认支持这三种:sans, serif, monospace。
  • ... 更多属性可参考官方文档:TextView (opens new window)

提示:

TextView 控件中的大多数属性一般都可以使用 xml 或者 代码 的方式来进行设置,如:text 属性,可以在 xml 中使用 android:text 属性进行设置或使用代码(java)setText(xxx) 的方式来设置。

字体还可以通过代码方式来使用其他字体文件(*.ttf):

  1. 先要将字体文件保存在assets/fonts/目录下

  2. Java代码中设置:

    Typeface typeFace = Typeface.createFromAsset(getAssets(),"fonts/HandmadeTypewriter.ttf"); textView.setTypeface(typeFace)。

示例:

xml布局

<TextView
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="This is a simple textview example!"
    android:background="#2196F3"
    android:gravity="center"
    android:textSize="20sp"
    android:textColor="#ccc"
    android:textStyle="bold"
    android:singleLine="true"
    android:ellipsize="middle"/>

效果:

Textview简单使用效果图

# drawable属性设置图片

drawableXxx,可以设置文本四个方向的图片:

drawableTop: 设置上面方向的drawable资源

drawableButtom: 设置下面方向的drawable资源

drawableLeft: 设置左侧方向的drawable资源

drawableRight: 设置右侧方向的drawable资源

drawablePadding:来设置图片与文字间的间距

示例:

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#787373">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_test"
        android:drawableTop="@drawable/icon_test"
        android:drawableRight="@drawable/icon_test"
        android:drawableBottom="@drawable/icon_test"
        android:drawablePadding="10dp"
        android:textColor="#00BCD4"
        android:textSize="15sp"
        android:text="图片文本"/>

</LinearLayout>

效果:

Textview带图片的效果图

drawableXxx 资源并不能在XML自行设置大小,所以我们需要在代码(Java)中来进行一个修改。

示例:

代码:

TextView tv = findViewById(R.id.tv_demo);
Drawable[] drawables = tv.getCompoundDrawables();
// 数组0~3下标,依次代表的是:左上右下的坐标点的位置
// 宽:距离文字左边缘开始50~150,高:距离文字顶部0~300
drawables[1].setBounds(50, 0, 150, 300);
// 为TextView重新设置drawable资源数组,没有图片可以用null代替
tv.setCompoundDrawables(drawables[0], drawables[1], drawables[2],drawables[3]);

效果:

Textview设置图片大小位置的效果图

# autoLink属性识别链接

当文字中含有网址(URL)email电话号码等等情况的时候,我们可以通过设置 autoLink 属性;当我们点击文字中对应部分的文字,即可跳转至某默认APP来处理,如:一个 web 网址,点击后跳转至 web 浏览器界面(存在的情况)。

属性

autoLink:有 web, phone, email, map, none, all 等属性设置自动识别的链接类型

all 就是全部都包含,自动识别协议头。

也可以在代码(Java)中可以使用 setAutoLinkMask(Linkify.ALL),此时 autolink 会自动识别,但是还要为这个 TextView 设置 setMovementMethod(LinkMovementMethod.getInstance()) 否则点击没有相应的动作效果。

示例:

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:autoLink="all"
        android:text="百度网址: www.baidu.com" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:autoLink="all"
        android:text="移动客服: 18212345678" />

</LinearLayout>

效果:

Textview 自动识别链接的效果图

# html格式支持

TextView 除了显示普通文本外,TextView 还预定义了一些类似于 HTML 的标签,通过这些标签,我们可以使 TextView 显示不同的字体颜色,大小,字体,甚至是显示图片,或者链接等等,只要使用 HTML 中的一些标记的标签,加上 android.text.HTML 类的支持,即可完成上述功能。

HTML (opens new window)(超文本标记语言——HyperText Markup Language)是构成 Web 世界的一砖一瓦。HTML 使用“标记”(markup)来注明文本、图片和其他内容,以便于在 Web 浏览器中显示。

Android 中也不是全部支持的,这里简单的列举几种常见的支持的标签:

  • <font>:设置颜色和字体
  • <big>:设置字体大号
  • <small>:设置字体小号
  • <i><b>:斜体粗体
  • <a>:链接网址
  • <img>:图片

示例:

示例代码:

TextView tv = findViewById(R.id.tv_demo);
// 设置带html便签的文本
// 红色字体颜色标签,加粗文本
String htmlTxt = "<font color='red'><b>百度一下:</b></font> ";
// 超链接标签
htmlTxt += "<a href = 'http://www.baidu.com'>点此进入百度</a>";
// 使用Html类进行格式设置
tv.setText(Html.fromHtml(htmlTxt));
// 需要设置此方法才能生效
tv.setMovementMethod(LinkMovementMethod.getInstance());

效果:

Textview html文字的效果图

对于图片标签的使用,需要使用 Html.ImageGetter 来进行处理。

示例:

示例代码:

TextView tvImg = findViewById(R.id.tv_img);
String htmlImg = "图片标签:<img src='icon_test' />";
tvImg.setText(Html.fromHtml(htmlImg, new Html.ImageGetter() {
    @Override
    public Drawable getDrawable(String source) {
        Context context = getBaseContext();
        int identifier = getResources().getIdentifier(source,
                                                      "drawable",
                                                      context.getPackageName());
        Drawable drawable = context.getResources().getDrawable(identifier);
        // 注意:如果不设置边界,无法显示
        drawable.setBounds(0,
                           0,
                           drawable.getIntrinsicWidth(),
                           drawable.getIntrinsicHeight());
        return drawable;
    }
}, null));

效果:

Textview html图片标签的效果图

# SpannableString富文本

SpannableString 可以实现文字的背景,颜色,删除线,下划线等等富文本功能。

常用的Api有:

  • BackgroundColorSpan:背景色
  • ClickableSpan:文本可点击,有点击事件
  • ForegroundColorSpan:文本颜色(前景色)
  • MaskFilterSpan:修饰效果,如模糊(BlurMaskFilter)、浮雕(EmbossMaskFilter)
  • MetricAffectingSpan:父类,一般不用
  • RasterizerSpan:光栅效果
  • StrikethroughSpan:删除线(中划线)
  • SuggestionSpan:相当于占位符
  • UnderlineSpan:下划线
  • AbsoluteSizeSpan:绝对大小(文本字体)
  • DynamicDrawableSpan:设置图片,基于文本基线或底部对齐。
  • ImageSpan:图片
  • RelativeSizeSpan:相对大小(文本字体)
  • ReplacementSpan:父类,一般不用
  • ScaleXSpan:基于x轴缩放
  • StyleSpan:字体样式:粗体、斜体等
  • SubscriptSpan:下标(数学公式会用到)
  • SuperscriptSpan:上标(数学公式会用到)
  • TextAppearanceSpan:文本外貌(包括字体、大小、样式和颜色)
  • TypefaceSpan:文本字体
  • URLSpan:文本超链接

示例:

示例代码:

TextView tv = findViewById(R.id.tv_demo);
SpannableString ss = new SpannableString("红色字体蓝色背景电话斜体下划线删除线可点击图片");
// 指定的flags: Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
// flags是对可以输入新文本的控件才会起作用,如果你是对TextView操作,flags用哪个都一样的
int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
// 下标从0开始的话,区间:[start, end]
// 标记文字颜色
ss.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, flags);
// 标记文字背景颜色
ss.setSpan(new BackgroundColorSpan(Color.BLUE), 4, 8, flags);
// 标记超链接文本
ss.setSpan(new URLSpan("tel:10086"), 8, 10, flags);
// 标记斜体文本
ss.setSpan(new StyleSpan(Typeface.ITALIC), 10, 12, flags);
// 标记下划线文本
ss.setSpan(new UnderlineSpan(), 12, 15, flags);
// 标记删除线文本
ss.setSpan(new StrikethroughSpan(), 15, 18, flags);
// 标记可点击的文本
ss.setSpan(new ClickableSpan() {
    @Override
    public void onClick(@NonNull View widget) {
        Toast.makeText(getBaseContext(), "可点击文本的点击事件", Toast.LENGTH_LONG).show();
    }
}, 18, 21, flags);
// 标记图片替换文本
Drawable drawable = getBaseContext().getResources().getDrawable(R.drawable.icon_test);
// 需要设置边界,否则无法显示
drawable.setBounds(0,
                   0,
                   drawable.getIntrinsicWidth(),
                   drawable.getIntrinsicHeight());
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
ss.setSpan(imageSpan, 21, 23, flags);
// 需要设置此方法才可以使用文本中的动作
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(ss);

效果:

Textview 富文本实现的效果图

# 文本跑马灯效果示例

这里简单实现一个 TextView 的跑马灯的效果。

示例:

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:id="@+id/tv_demo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:text="你好,世界! 你好,世界! 你好,世界! 你好,世界! 你好,世界! 你好,世界! "
        android:textSize="16sp"/>
    
</LinearLayout>

提示:

实现跑马灯的效果的话,除了上面的 xml 属性设置外,还需要控件获得 focus,在代码(java)中调用:requestFocus() 即可。

效果:

Textview 跑马灯实现的效果图

# 小结

到这里, TextView 控件的相关特性和常用的操作就介绍到这里了,还有未完善的地方,可以参考官方文档:TextView (opens new window)