开发中的 TextView 技巧点整理

4,172 阅读7分钟

转载请标明出处: www.jianshu.com/p/500f7a9ee…

本篇文章主要是记录一下日常开发中,对TextView控件的一些使用过的技巧的整理,仅限自己开发中用到的一些点,并不全面,也没有太多技术含量.只是为了方便一些程序员小伙伴用到得时候,搜到之后拿来即用。如发现有错误,烦请帮忙指证,谢谢!

本文主要罗列了以下技巧点:

  • 通过换行符换行
  • 在TextView中引入图片资源
  • 动态变换TextView中的图片资源
  • 设置字体和样式
  • 加载自定义字体
  • 限制TextView字符数
  • 多文字展示中常见的【显示全部-收起】
  • 价格标签与下划线
  • 文字描边与阴影
  • 跑马灯效果
  • 设置字间距与行间距

Demo动态图如下:


Demo动态图

1.通过换行符换行

非常基础的换行符“\n”的使用,有些时候在一些复杂ItemView中,会有上下两行TextView罗列用来展示内容的情况,如果两行TextView的字体样式一致,并且数据来源固定或统一,此时可以考虑用一个TextView搞定,能少绘制一个TextView,甚至是用来包裹他们的LineaLayout也省了。

代码:

<!--普通换行-->
 <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:background="@color/colorAccent"
      android:text="'好好学习\n天天向上" />

效果图:


通过换行符换行

2.在TextView中引入图片资源

一个图片+几个文字的的控件搭配在任何项目中都太常见了,比如


点赞

这个可以用LineaLayout来水平包裹ImageView+TextView,也可以直接通过TextView的drawableXxx属性来将图片资源嵌入TextView中。其中Xxx是指图片摆放的位置,包括

  • drawableLeft 左侧
  • drawableRight 右侧
  • drawableTop 上方
  • drawableBottom 下方
  • drawableStart 控件空间的起始位置
  • drawableEnd 控件空间的末尾

代码:

 <TextView
      android:id="@+id/tv_drawable"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dp"
      android:drawablePadding="10dp"
      android:drawableRight="@drawable/password_hide"
      android:gravity="center"
      android:text="点下试试" />

效果图:


在TextView中引入图片资源

3.动态变换TextView中的图片资源

上面谈到的图片+文字的两种布局方式中,LinearLayout水平包裹的方式虽然略显臃肿,但是动态替换其中的图片比较方便,直接操作包裹的ImageView即可。而TextView内嵌图片的方式,在动态替换图片资源时,略显繁琐,不过也很简单,主要是对Drawable对象的操作。

代码:

//1.通过图片资源获取Drawable对象
Drawable showPwdDrawable = getResources().getDrawable(R.drawable.password_show);
//2.设置Drawable对象的显示范围
showPwdDrawable.setBounds(0, 0, showPwdDrawable.getMinimumWidth(), showPwdDrawable.getMinimumHeight());
//3.将Drawable设置给TextView(方法中的4个参数,分别对应Drawable相对于文字而言放置的位置:左上右下四个位置)
textview.setCompoundDrawables(null, null, showPwdDrawable, null);

效果图:


动态变换TextView中的图片资源

4.设置字体和样式

TextView的typeface属性可以用来设置字体,默认有4种类型

  • normal
  • sans
  • serif
  • monospace

textStyle属性可以用来设置样式,默认有3种类型:

  • bold 粗体
  • italic 斜体
  • normal 正常(默认)

代码:

<!--粗体+serif样式-->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:text="@string/study"
    android:textStyle="bold"
    android:typeface="serif" />

<!--斜体 + monospace样式-->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:text="@string/study"
    android:textStyle="italic"
    android:typeface="monospace" />

效果图:


设置字体和样式

5.加载自定义字体

除了系统默认提供的几种字体以外,还可以加载自定义的字体.
注意:字体文件必须是真正的ttf(TrueTypeFont)文件,否则要么没有效果 , 要么直接抛java.lang.RuntimeException: Font asset not found fonts异常,.

步骤:
1.将ttf字体文件放在Module的src/main/assets/fonts/目录下
2.加载字体文件到内存,并设置给TextView

//通过Typeface的静态方法加载字体资源到内存
Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/华文行楷.ttf");
//将typeface设置给TextView
tvCustomTypeface.setTypeface(typeface);

效果图:


加载自定义字体

6.限制TextView字符数

为了UI效果或者屏幕适配等因素,经常需要对TextView展示出来的字数做限制,其实也很简单通过3个属性就可以搞定:

  • ellipsize 省略位置
  • maxEms 最大字符数,一个汉字占1个字符,1个英文/符号占半个字符;从第maxEms+1位置开始用省略号代替
  • maxLines 行数限制(singleLine也行,但是已被标记为Deprecated)
<!--限制字符数-->
<TextView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:ellipsize="end"
     android:maxLines="1"
     android:maxEms="7"
     android:text="@string/study" />

效果图:


限制TextView字符数

7.多文字展示中常见的【显示全部-收起】

这个比较常见,比如看个朋友圈或者微博,不会直接将文字内容全部罗列展示出来,而是末尾有个[更多]or[显示全部],点击后就会将文字内容全部显示出来.(当然也有点击后跳转页面的,跟这次谈的内容无关,这是举个例子)

实现起来也比较简单,通过setMaxLines(int maxLines)方法即可达到目的.

每次点击[显示全部-收起]按钮时 , 执行以下事件 , 即可实现 . 效果图请看文章开头的gif图.

showAll = !showAll;
if(showAll){
      tvShowAll.setMaxLines(2);
      btnShowAll.setText("查看全部");
  }else {
      tvShowAll.setMaxLines(20);
      btnShowAll.setText("收起");
  }

注意

开发中当碰到上述问题时,同时必然存在一个前提场景,那就是根据数据内容来动态判断是该展示 [显示全部]按钮.

此时需要动态获取textview加载了内容后占据了几行,比如我们需求规定超过3行,末尾就要省略+展示[显示更多] . 此时需要用到TextView的getLineCount()方法.

getLineCount() 方法
Return the number of lines of text, or 0 if the internal Layout has not been built.返回TextView内容的行数 , 如果没内容则返回0

需要注意的时,此方法不能直接在onCreate()中调用,因为此时TextView的内容可能还没有加载完毕导致获取到得行数为0.可以用如下方式来决定[显示全部]按钮是否显示

textview.post(new Runnable() {
    @Override
    public void run() {
        if(textview.getLineCount() > 3){
            //textview内容大于行数限制,展示[显示全部]按钮"
        }else {
            //textview内容小于等于行数限制"
        }
    }
});

8.价格标签与下划线

在商品交易类模块必然牵扯到商品价格 , 而一般出于促销目的,会在界面上展示出商品原价和现价 ,原价远高于现价, 同时再把原价划上一条横线表示作废以刺激客户消费 . 这是很常见的 价格促销UI.

这个效果需要TextView通过Paint对象来绘制,系统都封装好了,我们简单使用即可.

第一步,正常定义XML

<!--价格标签-->
<!--中间横线-->
<TextView
    android:id="@+id/tv_line_middle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="¥20.00"
    android:textColor="@android:color/holo_red_dark" />

<!--底部横线-->
<TextView
    android:id="@+id/tv_line_end"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:text="¥20.00"
    android:textColor="@android:color/holo_red_dark" />

第二步,通过TextView的Paint对象来划线

//中间横线
tvLineMiddle.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG );
//下划线
tvLineEnd.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);

效果图:


价格标签与下划线

9.文字描边与阴影

涉及属性:

  • shadowColor : Place a blurred shadow of text underneath the text, drawn with the specified color.用指定颜色在文字下方绘制模糊的阴影
  • shadowDx Horizontal offset of the text shadow. 文字阴影的横向/水平偏移量
  • shadowDy Vertical offset of the text shadow. 文字阴影的纵向/垂直偏移量
  • shadowRadius Blur radius of the text shadow. 阴影的半径范围
<!--文字描边与阴影-->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:shadowColor="#ff0000"
    android:shadowDx="5"
    android:shadowDy="5"
    android:shadowRadius="5"
    android:text="@string/study" />

效果图:


文字描边与阴影

10.跑马灯效果

现在这种效果用的越来越少了,不赘述了.

直接上代码,效果图见文章顶部gif:

<!--跑马灯效果-->
<TextView
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:background="@android:color/holo_blue_light"
    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:marqueeRepeatLimit="marquee_forever"
    android:singleLine="true"
    android:text="@string/poem" />

11.设置字间距与行间距

涉及属性:

  • letterSpacing 字间距
    • Must be a floating point value, such as "0.2". (0.0~1.0 stands for a letter) -----必须是0.0~1.0之间的小数,以一个字母为空间标准
  • lineSpacingExtra 行距
    • Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters). -----直接通过px,dp,sp等单位指定行距,例如14.5sp
  • lineSpacingMultiplier 行间距的倍数
    • Must be a floating point value, such as "1.2".----比如1.2倍

直接使用上述属性,即可达到设置字间距,行间距的目的,代码如下,效果图见文章顶部gif

 <!--字间距0.5字符-->
<TextView
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@android:color/darker_gray"
    android:letterSpacing="0.5"
    android:text="@string/poem" />

<!--行间距10sp-->
<TextView
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:background="@android:color/holo_green_light"
    android:lineSpacingExtra="10sp"
    android:text="@string/poem" />

<!--行间距1.8倍-->
<TextView
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:lineSpacingMultiplier="1.8"
    android:text="@string/poem" />

Demo下载地址