android:maxLines和android:ellipsize同时使用导致显示异常
16lz
2021-12-04
今天偶然发现android:maxLines和android:ellipsize这两个属性同时使用在某些设备上时不能正常工作,网上搜索了大半天最后终于还是在Stack-Overflow这个神奇的网上找到了一个满意的答案,原文地址如下:
http://stackoverflow.com/questions/2160619/android-ellipsize-multiline-textview
用法是将需要用到的TextView换成下面的EllipsizingTextView,然后在Java代码中使用setMaxLines(int maxLines)方法,直接传入一个所需要的最大行数即可,不需要再指定android:ellipsize参数或着使用setEllipsize这个方法(该方法在此类中被重写成了一个空方法,即不推荐使用的)
用这个方法基本上能在所有的设备上正常工作
需要注意的是,某情况使用如下的这三个属性可能也能实现
android:maxLines="4" android:ellipsize="marquee" android:singleLine="false"
但是这种方法只能在部分设备上正常显示,并不能保证所有设备都正常(本人亲测过),所以最好还是用下面的EllipsizingTextView来实现
另外这个类还提供了一个监听器EllipsizeListener,这个监听器原文作者说的是开始在Ellipsize(这个单词不知道怎么读,网上也查不到,估计是Google自创的)的时候调用的,大概意思应该就是说在开始省略(也就是开始 ”...“ )的时候调用,这个暂时还没有试过,等以后需要的时候再去试一试
EllipsizingTextView.java
[java] view plain copy print ?- import java.util.List;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.text.Layout;
- import android.text.Layout.Alignment;
- import android.text.StaticLayout;
- import android.text.TextUtils.TruncateAt;
- import android.util.AttributeSet;
- import android.widget.TextView;
- public class EllipsizingTextView extends TextView {
- private static final String ELLIPSIS = "...";
- public interface EllipsizeListener {
- void ellipsizeStateChanged(boolean ellipsized);
- }
- private final List
ellipsizeListeners = new ArrayList(); - private boolean isEllipsized;
- private boolean isStale;
- private boolean programmaticChange;
- private String fullText;
- private int maxLines = -1;
- private float lineSpacingMultiplier = 1.0f;
- private float lineAdditionalVerticalPadding = 0.0f;
- public EllipsizingTextView(Context context) {
- super(context);
- }
- public EllipsizingTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- public void addEllipsizeListener(EllipsizeListener listener) {
- if (listener == null) {
- throw new NullPointerException();
- }
- ellipsizeListeners.add(listener);
- }
- public void removeEllipsizeListener(EllipsizeListener listener) {
- ellipsizeListeners.remove(listener);
- }
- public boolean isEllipsized() {
- return isEllipsized;
- }
- @Override
- public void setMaxLines(int maxLines) {
- super.setMaxLines(maxLines);
- this.maxLines = maxLines;
- isStale = true;
- }
- public int getMaxLines() {
- return maxLines;
- }
- @Override
- public void setLineSpacing(float add, float mult) {
- this.lineAdditionalVerticalPadding = add;
- this.lineSpacingMultiplier = mult;
- super.setLineSpacing(add, mult);
- }
- @Override
- protected void onTextChanged(CharSequence text, int start, int before, int after) {
- super.onTextChanged(text, start, before, after);
- if (!programmaticChange) {
- fullText = text.toString();
- isStale = true;
- }
- }
- @Override
- protected void onDraw(Canvas canvas) {
- if (isStale) {
- super.setEllipsize(null);
- resetText();
- }
- super.onDraw(canvas);
- }
- private void resetText() {
- int maxLines = getMaxLines();
- String workingText = fullText;
- boolean ellipsized = false;
- if (maxLines != -1) {
- Layout layout = createWorkingLayout(workingText);
- if (layout.getLineCount() > maxLines) {
- workingText = fullText.substring(0, layout.getLineEnd(maxLines - 1)).trim();
- while (createWorkingLayout(workingText + ELLIPSIS).getLineCount() > maxLines) {
- int lastSpace = workingText.lastIndexOf(' ');
- if (lastSpace == -1) {
- break;
- }
- workingText = workingText.substring(0, lastSpace);
- }
- workingText = workingText + ELLIPSIS;
- ellipsized = true;
- }
- }
- if (!workingText.equals(getText())) {
- programmaticChange = true;
- try {
- setText(workingText);
- } finally {
- programmaticChange = false;
- }
- }
- isStale = false;
- if (ellipsized != isEllipsized) {
- isEllipsized = ellipsized;
- for (EllipsizeListener listener : ellipsizeListeners) {
- listener.ellipsizeStateChanged(ellipsized);
- }
- }
- }
- private Layout createWorkingLayout(String workingText) {
- return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),
- Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false);
- }
- @Override
- public void setEllipsize(TruncateAt where) {
- // Ellipsize settings are not respected
- }
- }
更多相关文章
- Android教程之Android(安卓)SDK1.5模拟器使用命令
- android手机屏幕适配方法
- 使用ProgressBar实现加载进度条
- Android(安卓)文字阴影、layer-list、shape和selector使用
- 基于Android(安卓)FrameLayout的使用详解
- Android(安卓)游戏设计教程
- Android测试原理(二)
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
- android UI进阶之弹窗的使用(2)--实现通讯录的弹窗效果