2013-02-04 41 views
12

Vấn đề tôi đang cố khắc phục như sau: Tôi đang có TextView và tôi đang sử dụng Spannable để đặt một số ký tự in đậm. Văn bản cần phải có tối đa 2 dòng (android:maxLines="2") và tôi muốn văn bản được tách rời, nhưng vì một lý do nào đó tôi không thể làm cho văn bản được bỏ qua.TextView sử dụng Spannable - ellipsize không hoạt động

Đây là mã đơn giản:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:orientation="vertical" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent"> 

    <TextView android:id="@+id/name" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:gravity="center" 
       android:maxLines="2" 
       android:ellipsize="end" 
       android:bufferType="spannable" 
       android:text="@string/app_name" 
       android:textSize="15dp"/> 

</LinearLayout> 

và hoạt động:

public class MyActivity extends Activity { 

    private TextView name; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     name= (TextView) findViewById(R.id.name); 


     name.setText("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy "); 
     Spannable spannable = (Spannable)name.getText(); 
     StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); 
     spannable.setSpan(boldSpan, 10, 15, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 

    } 
} 

Văn bản là cắt ngắn, không có "..." được hiển thị. enter image description here

Trả lời

4

Bạn đang ở trong hình elip đó, được khai báo trong xml hoặc mã sẽ không hoạt động trên văn bản có thể quét được.

Tuy nhiên, với một chút điều tra bạn thực sự có thể làm ellipsizing mình:

private TextView name; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    name= (TextView) findViewById(R.id.name); 
    String lorem = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy " 
    name.setText(lorem); 

    Spannable spannable = (Spannable)name.getText(); 
    StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); 
    spannable.setSpan(boldSpan, 10, 15, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
    int maxLines = 2; 
    // in my experience, this needs to be called in code, your mileage may vary. 
    name.setMaxLines(maxLines); 

    // check line count.. this will actually be > than the # of visible lines 
    // if it is long enough to be truncated 
    if (name.getLineCount() > maxLines){ 
     // this returns _1 past_ the index of the last character shown 
     // on the indicated line. the lines are zero indexed, so the last 
     // valid line is maxLines -1; 
     int lastCharShown = name.getLayout().getLineVisibleEnd(maxLines - 1); 
     // chop off some characters. this value is arbitrary, i chose 3 just 
     // to be conservative. 
     int numCharsToChop = 3; 
     String truncatedText = lorem.substring(0, lastCharShown - numCharsToChop); 
     // ellipsize! note ellipsis character. 
     name.setText(truncatedText+"…"); 
     // reapply the span, since the text has been changed. 
     spannable.setSpan(boldSpan, 10, 15, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
    } 

} 
9

Có cùng một vấn đề và dường như các công việc sau cho tôi:

Spannable wordtoSpan = new SpannableString(lorem); 
wordtoSpan.setSpan(new ForegroundColorSpan(0xffff0000), 0, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
wordtoSpan.setSpan(new ForegroundColorSpan(0xff00ffff), 20, 35, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
textView.setText(wordtoSpan); 

trong xml TextView có android:mutileLine đặt và android:ellipsize="end"android:singleLine="false;

+4

Bạn gợi ý cho tôi, tôi đã sử dụng 'textView.setText (spannableStringBuilder, TextView.BufferType.SPANNABLE)'. Chỉ cần sử dụng 'textView.setText (spannableStringBuilder)' và nó hoạt động. – Sylphe

+0

@ lannyf hoạt động như thế nào? Bạn có cùng vấn đề với op không? Tôi làm và điều đó không hiệu quả đối với tôi –

+0

@Sylphe Bất kỳ ý tưởng nào tại sao loại bộ đệm đó lại phá vỡ nó? – AdamMc331

10

Tôi nhận ra đây là một bài đăng rất cũ, nhưng nhìn thấy nó vẫn chưa được trả lời và tôi cũng gặp phải vấn đề này hôm nay tôi nghĩ tôi sẽ đăng một giải pháp cho vấn đề này. Hy vọng nó sẽ giúp ai đó trong tương lai.

ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver(); 
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
{ 
    @Override 
    public void onGlobalLayout() 
    { 
     ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver(); 
     viewTreeObserver.removeOnGlobalLayoutListener(this); 

     if (textView.getLineCount() > 5) 
     { 
      int endOfLastLine = textView.getLayout().getLineEnd(4); 
      String newVal = textView.getText().subSequence(0, endOfLastLine - 3) + "..."; 
      textView.setText(newVal); 
     } 
    } 
}); 
+0

nó làm việc cho tôi – kot331107

+0

tuy nhiên bạn đã đăng nó như là một giải pháp có thể :) – kot331107

2

này có thể một chút lừa bằng cách sử dụng phản ánh để giải quyết vấn đề này. Sau khi đọc mã nguồn của AOSP, trong TextView.java, DynamicLayout chỉ chứa một thành phần trường tĩnh có tên là sStaticLayout và nó được xây dựng bởi StaticLayout (null) mới mà không có bất kỳ tham số nào kể cả maxLines.

Do đó, doEllipsis sẽ luôn là sai vì mMaximumVisibleLineCount được đặt là Integer.MAX_VALUE theo mặc định.

boolean firstLine = (j == 0); 
boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount); 
boolean lastLine = currentLineIsTheLastVisibleOne || (end == bufEnd); 

    ...... 

if (ellipsize != null) { 
    // If there is only one line, then do any type of ellipsis except when it is MARQUEE 
    // if there are multiple lines, just allow END ellipsis on the last line 
    boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); 

    boolean doEllipsis = 
       (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && 
         ellipsize != TextUtils.TruncateAt.MARQUEE) || 
       (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && 
         ellipsize == TextUtils.TruncateAt.END); 
    if (doEllipsis) { 
     calculateEllipsis(start, end, widths, widthStart, 
       ellipsisWidth, ellipsize, j, 
       textWidth, paint, forceEllipsis); 
    } 
} 

Vì vậy, tôi mở rộng TextView và thực hiện một Xem tên EllipsizeTextView

public class EllipsizeTextView extends TextView { 
public EllipsizeTextView(Context context) { 
    super(context); 
} 

public EllipsizeTextView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public EllipsizeTextView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
} 

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
} 

public EllipsizeTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    StaticLayout layout = null; 
    Field field = null; 
    try { 
     Field staticField = DynamicLayout.class.getDeclaredField("sStaticLayout"); 
     staticField.setAccessible(true); 
     layout = (StaticLayout) staticField.get(DynamicLayout.class); 
    } catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 

    if (layout != null) { 
     try { 
      field = StaticLayout.class.getDeclaredField("mMaximumVisibleLineCount"); 
      field.setAccessible(true); 
      field.setInt(layout, getMaxLines()); 
     } catch (NoSuchFieldException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    if (layout != null && field != null) { 
     try { 
      field.setInt(layout, Integer.MAX_VALUE); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

}

vấn đề được giải quyết!

0

Một giải pháp đơn giản và làm việc

Đây là mã của tôi ->

<TextView 
     android:id="@+id/textViewProfileContent" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:singleLine="false" 
     android:ellipsize="end" 
     android:maxLines="3" 
     android:textSize="14sp" 
     android:textColor="#000000" /> 

SpannableStringBuilder sb = new SpannableStringBuilder(); 
SpannableString attrAdditional = new SpannableString(additionalText); 
       attrAdditional.SetSpan(new StyleSpan(TypefaceStyle.Bold), 0, additionalText.Length, 0);... 

sb.Append(attrAdditional);... 

ProfileContent.SetText(sb, **TextView.BufferType.Normal**); 

Result

0

enter image description here

https://github.com/lsjwzh/FastTextView có độ phân giải sạch cho việc này. Bạn nên bao bọc chuỗi kéo dài của bạn đầu tiên, sau đó ghi đè getSpans, getSpanStart, getSpanEnd ... https://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/android/text/EllipsisSpannedContainer.java

dòng 207 chỉ cho bạn cách để sử dụng. https://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java

Bạn cũng có thể sử dụng FastTextView thay vì Android TextView

Các vấn đề liên quan