和尚我最近调整一个小需求,为了整体显示效果,需要限制一部分文字的长度,超过的以…代替。 和尚我本想偷个懒,用 android:maxLength="6" 属性配合 android:maxLines="1" 以及 android:ellipsize="end" 来实现,但是只可限制字符床度为6,没有省略号。然后想起有一个 android:maxEms="6" 属性来实现,默认超过长度以省略号结束。结果发现并非按字符长度计算,和尚还是太天真了。
Tips1: android:singleLine="true" 属性已经在 API 中不建议使用,和尚我在现有的设备中测试与 android:maxLines="1" 属性效果完全一致。 Tips2: 在使用 android:maxEms="6" 属性时, TextView 的宽度需为 wrap_content 方式。
以下是和尚我测试时遇到的问题: 左侧是从 maxEms = “1” 开始递增到 “16”,右侧是测量文字所占的宽度:
纯汉字
纯字母
纯数字
测试发现:
TextView 源码中
/**
* Makes the TextView at most this many ems wide
*
* @attr ref android.R.styleable#TextView_maxEms
*/
@android.view.RemotableViewMethod
public void setMaxEms(int maxems) {
mMaxWidth = maxems;
mMaxWidthMode = EMS;
requestLayout();
invalidate();
}
/**
* @return the maximum width of the TextView, expressed in ems or -1 if the maximum width
* was set in pixels instead (using {@link #setMaxWidth(int)} or {@link #setWidth(int)}).
* 文本视图的最大宽度,以EMS表示,或如果宽度为1,则表示最大宽度
* 设置为像素(使用{@ Link LyStMax宽度(int)}或{@ Link LyStSuffelt(int)})
* @see #setMaxEms(int)
* @see #setEms(int)
*
* @attr ref android.R.styleable#TextView_maxEms
*/
public int getMaxEms() {
return mMaxWidthMode == EMS ? mMaxWidth : -1;
}
和尚我查阅相关资料以及自己的理解是:
主要代码:
// xml 中 TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxEms="6"
android:maxLines="1"
android:text="@string/test_str1" />
// Kotlin 获取文字宽度
fun getTextViewWidth(tv: TextView): String {
val spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
tv.measure(spec, spec)
val measuredWidthTicketNum = tv.getMeasuredWidth()
return measuredWidthTicketNum.toString()
}