android:maxLines和android:ellipsize同时使用导致显示异常

今天偶然发现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 ?
  1. import java.util.List;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.text.Layout;  
  6. import android.text.Layout.Alignment;  
  7. import android.text.StaticLayout;  
  8. import android.text.TextUtils.TruncateAt;  
  9. import android.util.AttributeSet;  
  10. import android.widget.TextView;  
  11.   
  12. public class EllipsizingTextView extends TextView {  
  13.     private static final String ELLIPSIS = "...";  
  14.   
  15.     public interface EllipsizeListener {  
  16.         void ellipsizeStateChanged(boolean ellipsized);  
  17.     }  
  18.   
  19.     private final List<EllipsizeListener> ellipsizeListeners = new ArrayList<EllipsizeListener>();  
  20.     private boolean isEllipsized;  
  21.     private boolean isStale;  
  22.     private boolean programmaticChange;  
  23.     private String fullText;  
  24.     private int maxLines = -1;  
  25.     private float lineSpacingMultiplier = 1.0f;  
  26.     private float lineAdditionalVerticalPadding = 0.0f;  
  27.   
  28.     public EllipsizingTextView(Context context) {  
  29.         super(context);  
  30.     }  
  31.   
  32.     public EllipsizingTextView(Context context, AttributeSet attrs) {  
  33.         super(context, attrs);  
  34.     }  
  35.   
  36.     public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {  
  37.         super(context, attrs, defStyle);  
  38.     }  
  39.   
  40.     public void addEllipsizeListener(EllipsizeListener listener) {  
  41.         if (listener == null) {  
  42.             throw new NullPointerException();  
  43.         }  
  44.         ellipsizeListeners.add(listener);  
  45.     }  
  46.   
  47.     public void removeEllipsizeListener(EllipsizeListener listener) {  
  48.         ellipsizeListeners.remove(listener);  
  49.     }  
  50.   
  51.     public boolean isEllipsized() {  
  52.         return isEllipsized;  
  53.     }  
  54.   
  55.     @Override  
  56.     public void setMaxLines(int maxLines) {  
  57.         super.setMaxLines(maxLines);  
  58.         this.maxLines = maxLines;  
  59.         isStale = true;  
  60.     }  
  61.   
  62.     public int getMaxLines() {  
  63.         return maxLines;  
  64.     }  
  65.   
  66.     @Override  
  67.     public void setLineSpacing(float add, float mult) {  
  68.         this.lineAdditionalVerticalPadding = add;  
  69.         this.lineSpacingMultiplier = mult;  
  70.         super.setLineSpacing(add, mult);  
  71.     }  
  72.   
  73.     @Override  
  74.     protected void onTextChanged(CharSequence text, int start, int before, int after) {  
  75.         super.onTextChanged(text, start, before, after);  
  76.         if (!programmaticChange) {  
  77.             fullText = text.toString();  
  78.             isStale = true;  
  79.         }  
  80.     }  
  81.   
  82.     @Override  
  83.     protected void onDraw(Canvas canvas) {  
  84.         if (isStale) {  
  85.             super.setEllipsize(null);  
  86.             resetText();  
  87.         }  
  88.         super.onDraw(canvas);  
  89.     }  
  90.   
  91.     private void resetText() {  
  92.         int maxLines = getMaxLines();  
  93.         String workingText = fullText;  
  94.         boolean ellipsized = false;  
  95.         if (maxLines != -1) {  
  96.             Layout layout = createWorkingLayout(workingText);  
  97.             if (layout.getLineCount() > maxLines) {  
  98.                 workingText = fullText.substring(0, layout.getLineEnd(maxLines - 1)).trim();  
  99.                 while (createWorkingLayout(workingText + ELLIPSIS).getLineCount() > maxLines) {  
  100.                     int lastSpace = workingText.lastIndexOf(' ');  
  101.                     if (lastSpace == -1) {  
  102.                         break;  
  103.                     }  
  104.                     workingText = workingText.substring(0, lastSpace);  
  105.                 }  
  106.                 workingText = workingText + ELLIPSIS;  
  107.                 ellipsized = true;  
  108.             }  
  109.         }  
  110.         if (!workingText.equals(getText())) {  
  111.             programmaticChange = true;  
  112.             try {  
  113.                 setText(workingText);  
  114.             } finally {  
  115.                 programmaticChange = false;  
  116.             }  
  117.         }  
  118.         isStale = false;  
  119.         if (ellipsized != isEllipsized) {  
  120.             isEllipsized = ellipsized;  
  121.             for (EllipsizeListener listener : ellipsizeListeners) {  
  122.                 listener.ellipsizeStateChanged(ellipsized);  
  123.             }  
  124.         }  
  125.     }  
  126.   
  127.     private Layout createWorkingLayout(String workingText) {  
  128.         return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),  
  129.                 Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false);  
  130.     }  
  131.   
  132.     @Override  
  133.     public void setEllipsize(TruncateAt where) {  
  134.         // Ellipsize settings are not respected   
  135.     }  
  136. }  

你可能感兴趣的:(android:maxLines和android:ellipsize同时使用导致显示异常)