TextView 多行超出指定行数结尾显示省略号 ● 解决方法

该文章介绍了如何在Android开发中让TextView在超出指定行数后显示省略号,通过添加布局监听器OnGlobalLayoutListener,动态判断行数并截取文本内容。示例代码展示了未超出和超出指定行数时的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

开发中很常见的需求:需要让 TextView 控件多行展示,并在超出限制行数后,在最后一行的末尾显示省略号;如果未超过限制行数,则正常显示即可。


实现代码

	private int mShowLine = -1;// 变量,存储指定显示的行数
    boolean showEllipsis = false;// 是否超出限制并添加省略号。true表示超出限制添加省略号
    /**
     * 【超出指定行数,在最后一行结尾添加省略号】
     * 【未超出支持行数,正常显示】
     * 如果设置了 maxLines 属性,跟 showLines 参数相比较,取较小值进行行数展示
     * @param tv 文本控件对象
     * @param showLines 指定展示行数
     * @param originText 原始文本
     */
    private void ellipsizeEnd(TextView tv, int showLines, String originText){
        if (tv == null || TextUtils.isEmpty(originText)){
            return;
        }

        mShowLine = showLines;
        tv.setText(originText);
        tv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                try {
                    int lineCount = tv.getLineCount();
                    System.out.println(":> ### lineCount = " + lineCount);

                    // 如果设置了 maxLine 属性的情况
                    if (tv.getMaxLines() > 0 && tv.getMaxLines() < mShowLine){
                        mShowLine = tv.getMaxLines();
                    }

                    // lineCount(实际展示行数) 、mShowLine(指定行数)
                    if (lineCount <= mShowLine){
                        mShowLine = lineCount;
                        showEllipsis = false;
                    }else {
                        showEllipsis = true;
                    }

                    // 需要在结尾添加省略号的情况
                    if (showEllipsis){
                        Layout layout = tv.getLayout();
                        int sum = 0;// 需要展示多少个字
                        for (int i = 0;i < mShowLine;i++){
                            sum += (layout.getLineEnd(i) - layout.getLineStart(i));
                        }
                        System.out.println(":> ### sum = " + sum);

                        String showStr = originText.substring(0, sum-3) + "...";
                        tv.setText(showStr);
                    }

                    // 及时的清除 OnGlobalLayoutListener 监听
                    if (Build.VERSION.SDK_INT >= 16) {
                        tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

思路如下:

  • 获取 ViewTreeObserver 对象,给其添加 OnGlobalLayoutListener 监听(当一个视图树的布局发生改变时,可以被 ViewTreeObserver 监听到)。
  • 在上面的监听方法中进行相关判断逻辑的编写。
  • 设置原始文本,获取到实际展示的行数 lineCount,然后跟指定需要展示的行数 mShowLine 进行比较,当 lineCount 更小时,说明超出限制了,需要在结尾添加省略号。
  • 假如 mShowLine 是 2 且是需要添加省略号的情况,那就获取前 mShowLine 行每行的字数总和 sum,然后截取原始字符的前 sum-3 个文本,最后再拼接上省略号 ... 文本即可。

示例演示

未超出指定行数

  • textview 控件 xml 声明如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity">

    <TextView
        android:id="@+id/tv_info"
        android:textSize="24sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="" />

</LinearLayout>
  • 调用如下:
String originText = "举目观天下,唯我最为珍。蓝天白云翠,山河任遨游。家园是田园,共筑梦想基。人民众志成城,祖国真可爱。山间溪水涟漪荡,树叶微动沙沙响。翠岭云霞相映照,远峰苍翠入云藏。";
ellipsizeEnd(tv_info, 3, originText);
  • 效果图示:

在这里插入图片描述


超出指定行数

  • 调用如下:
String originText = "举目观天下,唯我最为珍。蓝天白云翠,山河任遨游。家园是田园,共筑梦想基。人民众志成城,祖国真可爱。山间溪水涟漪荡,树叶微动沙沙响。翠岭云霞相映照,远峰苍翠入云藏。";
ellipsizeEnd(tv_info, 2, originText);
  • 效果图示:

在这里插入图片描述


总结

上面的方法可以放到一个工具类里,然后方便统一调用。然后基于上面的逻辑可以扩展出更多省略号位置展示的情况,同学们可以自己去尝试一下。


下期有缘再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值