2013-02-04 33 views
12

私が修正しようとしている問題は、次のとおりです。TextViewを持っていて、一部の文字を太字に設定するのにSpannableを使用しています。 テキストは2行(android:maxLines="2")の最大値を持つ必要があり、テキストを省略記号にしたいが、何らかの理由でテキストを省略することはできません。Spannable - ellipsizeを使用したTextViewが機能しない

<?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> 

と活動:

はここで簡単なコードである

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); 

    } 
} 

テキストが切り捨てられ、ない "..." が表示されます。 enter image description here

答えて

4

xmlまたはコードで宣言された楕円は、スパニング可能なテキストでは機能しません。

しかし、調査の少しであなたが実際に自分自身をellipsizing行うことができます。

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

は同じ問題を抱えて、私のために、次の作品を思わ:XMLで

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); 

のTextViewが持っていますandroid:mutileLineが設定され、android:ellipsize="end"、およびandroid:singleLine="falseです。

+4

を使用することができますhttps://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java

あなたは、私が '' textView.setText(spannableStringBuilder、TextView.BufferType.SPANNABLE)を使用していた、私を示唆しました。単に 'textView.setText(spannableStringBuilder)'を使うと動作します。 – Sylphe

+0

@lannyfどのようにこれは機能しますか?あなたは作戦と同じ問題がありますか?私はして、それは私のために動作しません –

+0

@Sylpheそのバッファ型がそれを壊した理由は? – AdamMc331

10

私はこれが非常に古い記事であることを認識していますが、未だに未回答であり、今日もこの問題にぶつかりました。うまくいけば、将来誰かを助けることでしょう。

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

それは私のために働いた – kot331107

+0

しかし、可能な解決策として投稿しました:) – kot331107

2

これは、この問題を解決するためにリフレクションを使用して、ちょっとしたトリックがあります。 AOSPのソースコードを読んだ後、TextView.javaのDynamicLayoutには、sStaticLayoutという名前の静的フィールドメンバーだけが含まれ、maxLinesを含む任意のパラメータなしで新しいStaticLayout(null)によって構築されます。

したがって、デフォルトではmMaximumVisibleLineCountがInteger.MAX_VALUEに設定されているため、doEllipsisは常にfalseになります。

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); 
    } 
} 

だから私はのTextViewを拡張し、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(); 
     } 
    } 
} 

}

問題解決という名前のビューを作ります!

0

シンプルかつ作業溶液

この私のコードです - >

<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 は、このためにクリーンな解像度を持っています。 https://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/android/text/EllipsisSpannedContainer.java

...あなたは、まずあなたのスパンの文字列をラッパーする必要があり が、その後getSpans、getSpanStart、getSpanEndを上書きライン207は、どのように使用する方法を示します。あなたはまた、代わりのAndroidのTextViewのFastTextView

関連する問題