优先显示两边内容,中间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
    评论
当 toast 展示内容过多时,可以通过设置 Toast 的显示时长和位置,以及使用自定义的 Toast 布局来解决省略号的问题。 1. 设置 Toast 的显示时长和位置 可以通过Toast类的 setDuration() 方法来设置 Toast 的展示时长,如下所示: ``` Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG); toast.setDuration(5000); // 5秒钟 ``` 可以将 duration 设置为一个较长的时间,来确保用户足够的时间看清楚 Toast 显示内容。 另外,当 Toast 显示内容过多时,可以通过 setGravity() 方法来设置 Toast 的显示位置,如下所示: ``` toast.setGravity(Gravity.CENTER, 0, 0); ``` 上述代码会将 Toast 居中显示。通过调整 setGravity() 方法的参数,可以将 Toast 显示在其他位置。 2. 使用自定义的 Toast 布局 可以通过 LayoutInflater 类来加载自定义的 Toast 布局,并在其中显示需要展示内容。自定义布局可以是一个 XML 文件,也可以是一个 View 对象。 以下是一个使用自定义布局的例子: ``` LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.custom_toast, (ViewGroup) findViewById(R.id.custom_toast_layout)); TextView text = (TextView) layout.findViewById(R.id.text); text.setText("需要显示内容"); Toast toast = new Toast(getApplicationContext()); toast.setDuration(Toast.LENGTH_LONG); toast.setView(layout); toast.show(); ``` 在上述代码中,我们使用自定义布局 custom_toast.xml,并在其中添加一个 TextView显示需要展示内容。然后,我们将该布局设置为 Toast 的 View,以此来展示自定义的 Toast。 通过使用自定义的 Toast 布局,我们可以自由地控制 Toast 的样式和显示内容,从而更好地展示需要展示内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值