android theme È possibile avere più stili all'interno di una TextView?




modificare textview android studio (14)

Potrebbe essere semplice come utilizzare il metodo length () di String:

  1. Dividi la stringa di testo nel file XML di Strings in tante stringhe secondarie (stringhe separate dal punto di vista di Android) quante ne hai bisogno di stili diversi, quindi potrebbe essere come: str1, str2, str3 (come nel tuo caso), che quando uniti insieme sono l'intera stringa singola che usi.

  2. E poi segui semplicemente il metodo "Span", proprio come ti sei presentato con il tuo codice - ma invece di una singola stringa, combina tutte le sottostringhe unendole in una singola, ognuna con uno stile personalizzato diverso.

Usi comunque i numeri, anche se non direttamente: non prendono più una forma hardcoded (come nel tuo codice) ora, ma vengono sostituiti con i metodi combinati length () (notare due stelle precedenti e suffixing lo str. length () al posto del numero assoluto per estinguere la modifica):

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

per la prima dimensione della stringa, quindi 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...

È possibile impostare più stili per parti di testo diverse 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.

Le attività comuni della guida dello sviluppatore e Come eseguirle in Android includono la selezione, l'evidenziazione o lo stile di parti 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 usa numeri di posizione espliciti all'interno del testo. C'è un modo più pulito per fare questo?


Anch'io

Che ne dici di usare una bella annotazione 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)
            }
        }
    }
}


L'elenco dei tag supportati è:

Se si utilizza una risorsa stringa, è possibile aggiungere alcuni stili semplici, come grassetto o corsivo usando la notazione HTML. I tag attualmente supportati sono: B (grassetto), I (corsivo), U (sottolineatura), TT (monospazio), BIG , SMALL , SUP (apice), SUB (pedice) e STRIKE (barrato). Quindi, ad esempio, in res/values/strings.xml potresti dichiararlo:

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

(Da http://developer.android.com/guide/faq/commontasks.html#selectingtext - link Web Archive, <resource> typ <resource> typo è in originale!)

Mostra anche che Html.fromHtml non è veramente necessario in casi semplici.


Spanny rende 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)

È più leggero utilizzare SpannableString invece del markup html. Mi aiuta a vedere esempi visivi quindi ecco una risposta supplementare.

Questa è una singola 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

  • Spiega il significato delle flag di Span come SPAN_EXCLUSIVE_EXCLUSIVE
  • Android con spanning, SpannedString, Spannable, SpannableString e CharSequence
  • Tipi di campate

Questo esempio è stato originariamente ispirato da here .


Stavo incontrando lo stesso problema. Potrei usare da HTML, ma ora sono Android, non Web, quindi ho deciso di provarlo. Devo localizzare questo però così ho dato un colpo usando il concetto di sostituzione delle stringhe. Ho impostato lo stile su TextView come lo stile principale, quindi ho semplicemente formato gli altri peices.

Spero che questo aiuti gli altri a cercare di fare la stessa cosa - non so perché questo non sia più facile nel framework.

Le mie stringhe assomigliano a questo:


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

Ecco 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 formattazione:


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

Come già detto, usa TextView.setText(Html.fromHtml(String))

E usa questi tag nella tua stringa formattata in Html:

<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-tags-supported-by-textview.html


Infatti, ad eccezione dell'oggetto Html, è possibile utilizzare anche le classi di tipi Spannable, ad esempio TextAppearanceSpan o TypefaceSpan e SpannableString insieme. La classe Html usa anche questi meccanismi. Ma con le classi di tipo Spannable, hai più libertà.


Un po 'fuori tema, ma ho trovato questo troppo utile per non essere menzionato qui.

Cosa succede se vorremmo leggere il testo Html dalla risorsa string.xml e quindi renderlo facile da localizzare. CDATA rende questo possibile:

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

Dal nostro codice Java ora possiamo 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 è successo.

Spero che sia utile per alcuni di voi!


Utilizzo di una classe secondaria ausiliaria come condivisioni di risorse stringa Android nella parte inferiore della pagina Web. Puoi avvicinarti creando CharSquences e dando loro uno stile.

Ma nell'esempio che ci danno, è solo per il grassetto, il corsivo e persino per colorare il testo. Avevo bisogno di racchiudere diversi stili in un CharSequence per impostarli in un TextView . Quindi a quella classe (l'ho chiamata 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 dal punto di vista l'ho aggiunto.

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

Spero che questo ti sia d'aiuto!


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

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

questo funziona bene per me


Se non hai voglia di usare html, puoi semplicemente 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);

Prova Html.fromHtml() e contrassegna il tuo testo con tag HTML grassetto e corsivo, ad esempio:

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

Ecco un modo semplice per farlo usando 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 testi in grassetto Alcuni testi in corsivo





textview