Domanda

È possibile impostare più stili per diverse parti di testo all'interno di un TextView?

Ad esempio, sto impostando il testo come segue:

tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3);

È possibile avere uno stile diverso per ogni elemento di testo?Ad esempio, riga1 grassetto, parola1 corsivo, ecc.

La guida per gli sviluppatori Attività comuni e come eseguirle in Android include Selezionare, evidenziare o applicare stili a porzioni di testo:

// Get our EditText object.
EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.
vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:
// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
// to force it to use Spannable storage so styles can be attached.
// Or we could specify that in the XML.

// Get the EditText's internal text storage
Spannable str = vw.getText();

// Create our span sections, and assign a format to each.
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Ma questo utilizza numeri di posizione espliciti all'interno del testo.Esiste un modo più pulito per farlo?

È stato utile?

Soluzione

Nel caso in cui, qualcuno si sta chiedendo come fare questo, ecco un modo: (! Grazie a Mark di nuovo)

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
            "<small>" + description + "</small>" + "<br />" + 
            "<small>" + DateAdded + "</small>"));

Per una lista non ufficiale di tag supportati da questo metodo, vedere o questa domanda>: Quali tag HTML sono supportati da Android TextView?

Altri suggerimenti

Prova Html.fromHtml(), e contrassegnare il testo con tag HTML grassetto e corsivo per esempio:

Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff");
textView.setText(text);

Leggermente fuori tema, ma l'ho trovato troppo utile per non essere menzionato qui.

E se volessimo leggere il testo Html da stringa.xml risorsa e quindi facilitarne la localizzazione. CDATA rendere questo possibile:

<string name="my_text">
  <![CDATA[
    <b>Autor:</b> Mr Nice Guy<br/>
    <b>Contact:</b> myemail@grail.com<br/>
    <i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i>
  ]]>
</string> 

Dal nostro codice Java ora potremmo utilizzarlo in questo modo:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setText(Html.fromHtml(getString(R.string.my_text))); 

Non mi aspettavo che funzionasse.Ma così è stato.

Spero che sia utile a qualcuno di voi!

Se non avete voglia di usare HTML, si può solo creare uno styles.xml e usarlo in questo modo:

TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);

text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

tv.setText(text, TextView.BufferType.SPANNABLE);

È peso più luce utilizzare un SpannableString anziché html markup. Mi aiuta a vedere esempi visivi: ecco una risposta supplementare.

 entrare descrizione dell'immagine qui

Questo è un singolo TextView.

// set the text
SpannableString s1 = new SpannableString("bold\n");
SpannableString s2 = new SpannableString("italic\n");
SpannableString s3 = new SpannableString("foreground color\n");
SpannableString s4 = new SpannableString("background color\n");
SpannableString s5 = new SpannableString("underline\n");
SpannableString s6 = new SpannableString("strikethrough\n");
SpannableString s7 = new SpannableString("bigger\n");
SpannableString s8 = new SpannableString("smaller\n");
SpannableString s9 = new SpannableString("font\n");
SpannableString s10 = new SpannableString("URL span\n");
SpannableString s11 = new SpannableString("clickable span\n");
SpannableString s12 = new SpannableString("overlapping spans\n");

// set the style
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag);
s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag);
s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag);
s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag);
s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag);
s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag);
s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag);
s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag);
s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag);
s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag);
s11.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show();
    }
}, 0, s11.length(), flag);
s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag);
s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag);
s12.setSpan(new UnderlineSpan(), 4, 11, flag);

// build the string
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(s1);
builder.append(s2);
builder.append(s3);
builder.append(s4);
builder.append(s5);
builder.append(s6);
builder.append(s7);
builder.append(s8);
builder.append(s9);
builder.append(s10);
builder.append(s11);
builder.append(s12);

// set the text view with the styled text
textView.setText(builder);
// enables clicking on spans for clickable span and url span
textView.setMovementMethod(LinkMovementMethod.getInstance());

ulteriore studio

Questo esempio è stato originariamente ispirato da href="http://androidcocktail.blogspot.com/2014/03/android-spannablestring-example.html" qui .

L'elenco dei tag supportati è:

  

Se si utilizza una risorsa di stringa, è possibile aggiungere un po 'di stile semplice, come il grassetto o corsivo utilizzando la notazione HTML. I tag attualmente supportati sono: B (grassetto), I (corsivo), U (sottolineare), TT (monospazio), BIG, SMALL, SUP (apice), SUB (pedice), e STRIKE (barrato). Così, per esempio, in res/values/strings.xml si potrebbe dichiarare questo:

<resource>
    <string id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

( http://developer.android.com/guide/faq/commontasks.html#selectingtext - link archivio, <resource> errore di battitura è in originale)

Si dimostra anche che Html.fromHtml non è realmente necessario nei casi più semplici.

Sono stato in esecuzione nello stesso problema. Potrei usare fromHtml, ma io sono Android ora, non web, così ho deciso di provare questo fuori. Devo localizzare questo, però così mi hanno dato un colpo usando il concetto di sostituzione della stringa. Ho impostato lo stile del TextView ad essere lo stile principale, poi basta formattare le altre peices.

Spero che questo aiuta gli altri che cercano di fare la stessa cosa -. Non so perché questo non è facile nel quadro

Le mie corde simile a questa:


<string name="my_text">{0} You will need a {1} to complete this assembly</string>
<string name="text_sub0">1:</string>
<string name="text_sub1">screwdriver, hammer, and measuring tape</string>

Qui ci sono gli stili:


<style name="MainStyle">
    <item name="android:textSize">@dimen/regular_text</item>
    <item name="android:textColor">@color/regular_text</item>
</style>
<style name="style0">
    <item name="android:textSize">@dimen/paragraph_bullet</item>
    <item name="android:textColor">@color/standout_text</item>
    <item name="android:textStyle">bold</item>
</style>
<style name="style1">
    <item name="android:textColor">@color/standout_light_text</item>
    <item name="android:textStyle">italic</item>
</style>

Ecco il mio codice che chiama il mio metodo formatStyles:


SpannableString formattedSpan = formatStyles(getString(R.string.my_text), getString(R.string.text_sub0), R.style.style0, getString(R.string.main_text_sub1), R.style.style1);
textView.setText(formattedSpan, TextView.BufferType.SPANNABLE);

Il metodo di formato:


private SpannableString formatStyles(String value, String sub0, int style0, String sub1, int style1)
{
    String tag0 = "{0}";
    int startLocation0 = value.indexOf(tag0);
    value = value.replace(tag0, sub0);

    String tag1 = "{1}";
    int startLocation1 = value.indexOf(tag1);
    if (sub1 != null && !sub1.equals(""))
    {
        value = value.replace(tag1, sub1);
    }

    SpannableString styledText = new SpannableString(value);
    styledText.setSpan(new TextAppearanceSpan(getActivity(), style0), startLocation0, startLocation0 + sub0.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    if (sub1 != null && !sub1.equals(""))
    {
        styledText.setSpan(new TextAppearanceSpan(getActivity(), style1), startLocation1, startLocation1 + sub1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return styledText;
}

Ora l'elemento <b> è deprecato. <strong> rende come <b>, e <em> rende come <i>.

tv.setText(Html.fromHtml("<strong>bold</strong> and <em>italic</em> "));

questo funziona bene per me

Se si vuole essere in grado di aggiungere il testo in stile in XML è possibile creare una vista personalizzata che si estende TextView e sovrascrivere setText ():

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

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

    public HTMLStyledTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type)
    {
       super.setText(Html.fromHtml(text.toString()), type);
    }
}

Quindi, è possibile utilizzarlo come questo (sostituire PACKAGE_NAME con il nome del pacchetto):

<PACKAGE_NAME.HTMLStyledTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="<![CDATA[
        <b>Bolded Text:</b> Non-Bolded Text
    ]]>"
/>

Ecco un modo semplice per farlo utilizzando HTMLBuilder

    myTextView.setText(new HtmlBuilder().
                    open(HtmlBuilder.Type.BOLD).
                    append("Some bold text ").
                    close(HtmlBuilder.Type.BOLD).
                    open(HtmlBuilder.Type.ITALIC).
                    append("Some italic text").
                    close(HtmlBuilder.Type.ITALIC).
                    build()
    );

Risultato:

Alcuni testo in grassetto Alcuni testo in corsivo

Come già detto, l'uso TextView.setText(Html.fromHtml(String))

E utilizzare questi tag nel codice HTML stringa formattata:

<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>

http: // commonsware. com / blog / Android / 2010/05/26 / html-tag-supportati-by-textview.html

Me Too

Come sull'utilizzo delle belle markup con Kotlin e Anko -

import org.jetbrains.anko.*
override fun onCreate(savedInstanceState: Bundle?) {
    title = "Created with Beautiful Markup"
    super.onCreate(savedInstanceState)

    verticalLayout {
        editText {
            hint = buildSpanned {
                append("Italic, ", Italic)
                append("highlighted", backgroundColor(0xFFFFFF00.toInt()))
                append(", Bold", Bold)
            }
        }
    }
}

Creato con Bella Markup

Si, è possibile utilizzando SpannedString. Se si utilizza Kotlin, diventa ancora più facile da fare utilizzando core-ktx, in quanto fornisce una dominio-specifico della lingua (DSL) In questo modo:

    val string: SpannedString = buildSpannedString {
        bold {
            append("1111")
        }
        append("Devansh")     
    }

Altre opzioni da esso forniti sono:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

Alla fine, si può semplicemente a:

textView.text = string

In realtà, tranne l'oggetto HTML, è anche possibile utilizzare le classi di tipo Spannable, per esempio TextAppearanceSpan o TypefaceSpan e SpannableString togather. classe html utilizza anche questi meccanismi. Ma con le classi di tipo Spannable, hai più libertà.

Potrebbe essere semplice come sfruttando il metodo della stringa di lunghezza ():

  1. dividere la stringa di testo nel file XML Stringhe in altrettante sotto-stringhe (a separate stringhe dal punto di vista di Android), come molti avete bisogno di stili diversi, in modo che possa essere come: str1, str2 , str3 (come nel tuo caso), che una volta uniti sono l'intera stringa singolo si utilizza.

  2. E poi semplicemente seguire il metodo "Span", proprio come si presenterà con il proprio codice -. Ma invece di una singola stringa, unire tutte le sottostringhe loro si fondono in una sola, ognuno con un diverso stile personalizzato

Si usano ancora i numeri, tuttavia, non direttamente - non sono più sono assumere una forma hardcoded (come nel codice) ora, ma sono e viene sostituito con la lunghezza complessiva () metodi (si noti due stelle precedente e suffisso lo str.length () al posto del numero assoluto di extuinguish il cambiamento):

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

per la prima dimensione della stringa, allora str.length () + 1, str.length () + str2.length () per la seconda dimensione della stringa, e così via con tutte le sottostringhe, invece di es 0,7 o 8,19 e così via ...

Utilizzando una classe ausiliaria Spannable come Android String Risorse azioni nella parte inferiore della pagina web. È possibile avvicinarsi a questo da creatingCharSquences e dando loro uno stile.

Ma l'esempio che ci danno, è solo per il grassetto, corsivo, e anche colorare il testo. Avevo bisogno di avvolgere diversi stili in aCharSequence al fine di metterli in un TextView. Quindi, per quella Classe (ho chiamato CharSequenceStyles) Ho appena aggiunto questa funzione.

public static CharSequence applyGroup(LinkedList<CharSequence> content){
    SpannableStringBuilder text = new SpannableStringBuilder();
    for (CharSequence item : content) {
        text.append(item);
    }
    return text;
}

E nella vista ho aggiunto questo.

            message.push(postMessageText);
            message.push(limitDebtAmount);
            message.push(pretMessageText);
            TextView.setText(CharSequenceStyles.applyGroup(message));

Spero che questo aiuto voi!

Spanny rendere SpannableString più facile da usare.

Spanny spanny = new Spanny("Underline text", new UnderlineSpan())
                .append("\nRed text", new ForegroundColorSpan(Color.RED))
                .append("\nPlain text");
textView.setText(spanny)

detto , per me questa è la soluzione migliore e non avete bisogno di impostare qualsiasi testo in fase di runtime, utilizzare solo questa classe HtmlTextView personalizzato

public class HtmlTextView extends TextView {

  public HtmlTextView(Context context) {
      super(context);
  }

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

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

  @TargetApi(21)
  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  @Override
  public void setText(CharSequence s,BufferType b){
      super.setText(Html.fromHtml(s.toString()),b);
  }

}

e questo è tutto, ora solo metterlo in XML

<com.fitc.views.HtmlTextView
    android:id="@+id/html_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/example_html" />

con la stringa HTML

<string name="example_html">
<![CDATA[
<b>Author:</b> Mr Donuthead<br/>
<b>Contact:</b> me@donut.com<br/>
<i>Donuts for life </i>
]]>

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top