优先显示两边内容,中间TextView内容尾部省略号

我也不知道这个情景用什么内容来描述,就是我们在做一种卡片布局时,底部的内容是作者头像->作者信息->标签或者来源,然后pm要求两边内容显示完全,中间内容如果空间不够,尾部用...代替,需求乍一听没什么问题,ellipsize属性加maxLine="1"不就搞定了,然后出去试了一波不到两分钟就回来了,因为ellipsiize属性并没有生效,反而把末尾的内容挤没了。那么今天,博主就说出两种自己的思路,大家仅供参考。话不多说,先上图:

第一种解决方式:使用ConstraintLayout(不熟悉此布局的可以去学习下,实在不想学习就复制粘贴吧)

这会用到此布局的chain属性,在xml里面需要有省略号的控件设置app:layout_constraintHorizontal_chainStyle="packed",这样会优先显示另外的控件文案,代码如下

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
  >
  <TextView
      android:id="@+id/tv"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="关注好的反倒是地方"
      android:background="#0F0"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toStartOf="@+id/tv2"
      />
    >
  <TextView
      android:id="@+id/tv2"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:text="你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好"
      android:ellipsize="end"
      android:layout_marginLeft="5dp"
      android:layout_marginRight="5dp"
      android:singleLine="true"
      android:textColor="@color/black"
      app:layout_constraintHorizontal_chainStyle="packed"
      android:background="#f00"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintStart_toEndOf="@+id/tv"
      app:layout_constraintEnd_toStartOf="@+id/tv3"

      />

  <TextView
      android:id="@+id/tv3"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="关注"
      android:background="#0F0"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintStart_toEndOf="@+id/tv2"
      app:layout_constraintEnd_toEndOf="parent"
      />
</androidx.constraintlayout.widget.ConstraintLayout>

第二种解决方式:先把两边的View需要的宽度算出来,给两个的View设置上width,然后把剩余的空间给到中间的View,比较复杂。代码如下:

xml布局:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
  >
  <TextView
      android:id="@+id/tv4"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:background="#0f0"
    />
  <TextView
      android:id="@+id/tv5"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:maxLines="1"
      android:ellipsize="end"
      android:background="#f00"
    />
  <TextView
      android:id="@+id/tv6"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:background="#0f0"
    />
</LinearLayout>

java代码:

fun start() {
    // 获取屏幕宽度
    val manager: WindowManager = this.windowManager
    val outMetrics: DisplayMetrics = DisplayMetrics()
    manager.defaultDisplay.getMetrics(outMetrics);
    // 首先拿到布局的总宽度
    var layoutWidth = outMetrics.widthPixels

    // 需要先给TextView的text赋值,才能测量出总宽度
    tv4?.text = "这是左边的控件"
    // 先减去左边控件的宽度,为了拿到tv4的宽度,先进行测量
    tv4?.measure(0,0)
    val leftViewWidth = tv4?.measuredWidth
    if (leftViewWidth != null) {
        layoutWidth -= leftViewWidth
    }

    //然后用同样的方式减去右边的宽度
    tv6?.text = "这是右边的控件"
    tv6?.measure(0,0)
    val rightViewWidth = tv6?.measuredWidth
    if (rightViewWidth != null) {
        layoutWidth -= rightViewWidth
    }

    // 剩余的就是空间就都是中间View的了
    val lp = tv5?.layoutParams
    lp?.let {
        it.width = layoutWidth
    }
    tv5?.text = "你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好"
}

这样,效果同样是上面的效果啦,OK,到此为止,基本就把问题解决了,但是,ellipsize这个属性比较恶心,在有的版本或机型上,最后的三个省略号距离尾部会有一定间距,没法控制,如果UI走查比较严格,还得需要解决,我们的思路是算出每个文字的宽度,然后用剩余宽度除以每个文字的宽度,看看能放下几个字,然后剩余的手动用...拼接,代码如下:

    val text = "你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好"
    // 需要的宽度
    val needWidth = tv5.paint.measureText(text)
    if (needWidth > layoutWidth) {
        // 当前位置能放下的文字数量
        var stringNum = tv5.paint.breakText(text, true, layoutWidth.toFloat(), null)
        if (stringNum > 1) {
            // 因为要拼接... ,所以要减去一个文字的距离
            var subAuthText = text.substring(0, stringNum)
            // 这个StringUtils是用来判断是否以英文字母结尾
            if (StringUtils.checkEndForEnglish(subAuthText)) {
                // 如果截断的文字是以字母结尾,只截断一个字母的距离是不足以放下...的,所以默认截取三个字母
                var loopCount = 3
                while (loopCount > 0 && stringNum > 1) {
                    stringNum --
                    subAuthText = subAuthText.substring(0, stringNum)
                    if (!StringUtils.checkEndForEnglish(subAuthText)) {
                        break
                    }
                    loopCount --
                }
                // 如果loopCount大于0,代表文字后小于3个字母,为了兼容,还得再减去一个字的距离
                if (loopCount > 0 && stringNum > 1) {
                    stringNum --
                    subAuthText = subAuthText.substring(0, stringNum)
                }
            } else {
                stringNum --
                subAuthText = subAuthText.substring(0, stringNum)
            }
            val desc = StringBuilder().append(subAuthText)
                .append("...")
                .toString()
            tv5.text = desc
        }
    }
}

最后附上StringUtils的代码

object StringUtils {
    /**
     * 判断是否是英文字母结尾
     */
    fun checkEndForEnglish(str: String): Boolean {
        val c = str[str.length - 1]
        return (c in 'a'..'z' || c in 'A'..'Z')
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android自定义TextView显示全部内容,可以使用以下两种方法: 1. 使用setEllipsize()方法 通过设置setEllipsize()方法,可以在TextView的末尾添加省略号,从而指示文本被截断。你可以使用以下代码来实现: ``` yourTextView.setEllipsize(TextUtils.TruncateAt.END); yourTextView.setSingleLine(true); ``` 上述代码将设置TextView显示一行并在末尾添加省略号。 2. 自定义TextView 你可以从TextView类继承一个新类,并覆盖onMeasure()方法以测量控件的高度和宽度。 你可以使用以下代码实现: ``` public class CustomTextView extends TextView { public CustomTextView(Context context) { super(context); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取TextView内容 CharSequence text = getText(); if (text != null) { //测量TextView的高度 int width = getMeasuredWidth(); int height = getMeasuredHeight(); int lineCount = getLineCount(); int lineHeight = getLineHeight(); int totalHeight = lineCount * lineHeight; if (totalHeight > height) { setMeasuredDimension(width, totalHeight); } } } } ``` 上述代码将测量TextView的高度,如果文本的高度超出了TextView的高度,则调整TextView的高度以适应文本。然后你可以使用此自定义TextView显示你的文本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值