TextView utilizzando Spannable – ellipsizzazione non funziona

Il problema che cerco di risolvere è il seguente: sto avendo un TextView e sto usando una Spannable chiave Spannable per impostare alcuni caratteri grassetti. Il text deve avere un massimo di 2 righe ( android:maxLines="2" ) e voglio che il text venga elipsuito, ma per qualche motivo non posso rendere ellesso il text.

Ecco il codice semplice:

  • Solo applicazioni di posta elettronica per risolvere un intento
  • Android - Regola lo schermo quando la tastiera viene visualizzata?
  • Android MediaCodec decodifica il frame raw h264
  • Cambiare Locale all'interno dell'applicazione stessa
  • La scrittura di archiviazione esterna non funziona finché non riavvierò l'applicazione su Android M
  • lancio della mia applicazione quando componi un numero
  •  <?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> 

    e l'attività:

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

    Il text è troncato, non vengono visualizzati "…". immettere qui la descrizione dell'immagine

    6 Solutions collect form web for “TextView utilizzando Spannable – ellipsizzazione non funziona”

    Avendo lo stesso problema e sembra per me i seguenti lavori:

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

    in xml il textView ha android:mutileLine set android:mutileLine e android:ellipsize="end" e android:singleLine="false ;

    Mi rendo conto che questo è un post molto vecchio, ma visto che è ancora senza risposta e ho anche incontrato in questo problema oggi ho pensato di submit una soluzione a questo. Speriamo che qualcuno possa aiutare in futuro.

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

    Hai ragione in quello ellisse, dichiarato in xml o in codice non functionrà sul text spannable.

    Tuttavia, con un po 'di indagine si può effettivamente fare l'ellissezione te stesso:

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

    Questo è un problema noto nel framework Android: https://code.google.com/p/android/issues/detail?id=67186

    Questo potrebbe essere un piccolo trucco utilizzando la riflessione per risolvere questo problema. Dopo aver letto il codice sorgente di AOSP, in TextView.java, DynamicLayout contiene solo un membro di field statico denominato sStaticLayout e viene costruito con il nuovo StaticLayout (null) senza alcun parame, inclusi maxLines.

    Di conseguenza, il doEllipsis sarà sempre falso, poiché mMaximumVisibleLineCount è impostato come Integer.MAX_VALUE per impostazione predefinita.

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

    Così estendo il TextView e facendo una vista denominata 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(); } } } 

    }

    problema risolto!

    Una soluzione semplice e funzionante

    Questo è il mio codice ->

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

    Risultato

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.