Imposta lo stile per TextView a livello di codice


249

Sto cercando di usare il TextViewcostruttore con uno stile come questo:

TextView myText = new TextView(MyActivity.this, null, R.style.my_style);

Tuttavia, quando lo faccio, la visualizzazione del testo non sembra prendere lo stile (ho verificato lo stile impostandolo su un oggetto statico).

Ho anche provato a usare myText.setTextAppearance(MyActivity.this, R.style.my_style)ma anche non funziona.

Risposte:


318

Non credo che tu possa impostare lo stile programmaticamente. Per ovviare a questo è possibile creare un file xml di layout modello con lo stile assegnato, ad esempio in res / layout creare tvtemplate.xml come con il seguente contenuto:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This is a template"
        style="@style/my_style" />

quindi gonfiare questo per creare un'istanza del nuovo TextView:

TextView myText = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);

Spero che questo ti aiuti.


1
Dove questo vince sulla risposta di Dandre Allison è che non richiede API v11.
Martin Capodici,

2
Potrebbe aver funzionato, ma questo non ha senso. Come può essere impostato con il file xml? se non programmaticamente . Ci sono ragioni per non usare i file xml, uno di questi è che sono abituato a scrivere codice per creare l'interfaccia utente, quindi non voglio imparare un nuovo modo di farlo poiché la mia memoria è limitata e voglio lasciare spazio per altre cose.
Iharob Al Asimi,

@IharobAlAsimi è vero, tutto può essere fatto a livello di codice e LayoutInflater sa tutto sulla trasformazione di XML in oggetti. Purtroppo, molte cose del genere sono nascoste sotto API private e l'unico modo per creare alcuni oggetti è fornire AttributeSet al costruttore.
Miha_x64,

A differenza di tutte le altre risposte, in realtà ha funzionato con i filatori, quindi una stella d'oro per te
Rowan Berry,

121

È possibile creare uno stile generico e riutilizzarlo su più visualizzazioni di testo come quello riportato di seguito:

textView.setTextAppearance(this, R.style.MyTextStyle);

Modifica: si riferisce al contesto


50
La tua risposta funziona fintanto che tutto ciò che fai è il monkeying con lo "stile" del testo. Non funziona se si sta tentando di eseguire altre operazioni su TextView come aggiungere padding o margini. Quindi, non sto dicendo che ti sbagli, ma la tua risposta è limitata. Gonfiare la vista in fase di esecuzione è l'unico modo per applicare uno stile completo.
Bill Mote,

1
Entrambe le soluzioni di utilizzo di un modello gonfiato e utilizzo di setTextAppearance sono ragionevoli. Per risolvere il problema di riempimento / margini per la seconda soluzione, è possibile chiamare textView.setLayoutParams (layoutParams)
AlanKley

Questo metodo è stato deprecato a livello di API 23. Utilizzare setTextAppearance (int) anziché in API 23+.
Sergii,

Assicurati che la versione sia almeno API 23 (M)
Br0thazS0ul

4
usa il metodo dalla libreria di supporto,TextViewCompat.setTextAppearance
Rubin Yoo,

97

Puoi passare un ContextThemeWrapper al costruttore in questo modo:

TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));

1
grandi cose! l'unico modo in cui ho potuto impostare gli stili in modo programmatico supportando l'API 8.
tbraun,

Per qualche motivo, non influisce sullo stile del mio pulsante. Ho definito il mio stile come: <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. E poi invoco con una costruzione: new Button(new ContextThemeWrapper(context, R.style.TabButton));. Ma il pulsante ignora semplicemente le mie impostazioni. Sto facendo qualcosa di sbagliato qui?
Aleks N.

@ AlaksiejN. Dovresti ereditare da Widget.Button in questo modoparent="@android:style/Widget.Button"
maxcanna

@maxcanna Per qualche motivo l'aggiunta parentnon è cambiata un po '. Quindi sono andato avanti con la inflatesoluzione.
Aleks N.

11
@AliakseiN. È necessario utilizzare il costruttore 3-arg, ad es new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). In caso contrario, verrà applicato lo stile pulsante predefinito e questo stile sovrascriverà lo stile pulsante che è stato unito al tema tramite ContextThemeWrapper.
Newtonx,

17

È possibile impostare lo stile nel costruttore (ma gli stili non possono essere modificati / impostati in modo dinamico).

View(Context, AttributeSet, int)( intè un attributo nel tema corrente che contiene un riferimento a uno stile)

Risposta di Romain Guy

riferimento


la tua risposta è fuorviante - hai provato a leggere questa discussione fino alla fine?
andr

3
Come è fuorviante? La risposta accettata è fuorviante, perché Romain Guy afferma esplicitamente che è possibile "impostare" uno stile a livello di codice. Non c'è proprio la possibilità di cambiarlo in modo dinamico. Questo thread non sembra pensare che sia così.
Dandre Allison,

1
Attenzione, questa chiamata richiede il livello API 11.
Martin Capodici,

1
@PaulVerest non è un preventivo.
Dandre Allison,

6
L'ultimo int non è una risorsa di stile. È "Un attributo nel tema corrente che contiene un riferimento a una risorsa di stile che fornisce valori predefiniti per la vista".
rve

11

Il parametro int defStyleAttrnon specifica lo stile. Dalla documentazione di Android:

defStyleAttr : un attributo nel tema corrente che contiene un riferimento a una risorsa di stile che fornisce valori predefiniti per la vista. Può essere 0 per non cercare i valori predefiniti.

Per impostare lo stile in Visualizza costruttore abbiamo 2 possibili soluzioni:

  1. Con l'uso di ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
  2. Con il costruttore a quattro argomenti (disponibile a partire da LOLLIPOP):

    TextView textView = new TextView(yourContext, null, 0, R.style.your_style);

Cosa fondamentale per entrambe le soluzioni: il defStyleAttrparametro dovrebbe essere 0 per applicare il nostro stile alla vista.


5

Gli stili che cambiano dinamicamente non sono supportati (ancora). Devi impostare lo stile prima di creare la vista, tramite XML.


20
che sembra essere la stessa cosa, in realtà
njzk2

@njzk2 grazie ... ovviamente non ho pensato al suo commento prima di pubblicare. Non è possibile impostare lo stile a livello di codice prima della creazione dell'interfaccia utente, quindi lo stesso codice verrebbe utilizzato per modificare o impostare lo stile a livello di codice.
Chris Cashwell,

3

La risposta accettata è stata un'ottima soluzione per me. L'unica cosa da aggiungere riguarda il inflate()metodo.

Nella risposta accettata android:layout_*non verranno applicati tutti i parametri.

Il motivo non è un modo per regolarlo, la causa è nullstata approvata come ViewGroup parent.

Puoi usarlo in questo modo:

View view = inflater.inflate(R.layout.view, parent, false);

e il parentè il ViewGroup, da dove ti piace regolare android:layout_*.

In questo caso, verranno impostate tutte le proprietà relative.

Spero che sia utile per qualcuno.


2

Quando si utilizzano viste personalizzate che possono utilizzare l'ereditarietà degli stili (o gli attributi di stile degli eventi), è necessario modificare il secondo costruttore per non perdere lo stile. Questo ha funzionato per me, senza bisogno di usare setTextAppearence () :

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}

2

Ho riscontrato anche il problema e ho trovato il modo di impostare lo stile in modo programmatico. Forse ne avrete bisogno tutti, quindi aggiorno lì.

Il terzo parametro del costruttore View accetta un tipo di attr nel tuo tema come codice sorgente di seguito:

public TextView(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

Quindi devi passare un tipo di R.attr. ** piuttosto che R.style. **

Nei miei codici, ho fatto i seguenti passi:

Innanzitutto, personalizza un attr personalizzato da utilizzare per i temi in attr.xml.

<attr name="radio_button_style" format="reference" />

In secondo luogo, specifica il tuo stile nel tema utilizzato in style.xml.

 <style name="AppTheme" parent="android:Theme.Translucent">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    <item name="radio_button_style">@style/radioButtonStyle</item>
</style>
<style name="radioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">64dp</item>
    <item name="android:background">#000</item>
    <item name="android:button">@null</item>
    <item name="android:gravity">center</item>
    <item name="android:saveEnabled">false</item>
    <item name="android:textColor">@drawable/option_text_color</item>
    <item name="android:textSize">9sp</item>
</style>

Alla fine, usalo!

            RadioButton radioButton = new RadioButton(mContext, null, R.attr.radio_button_style);

la vista creata a livello di codice utilizzerà lo stile specificato nel tema.

Puoi provare e spero che possa funzionare perfettamente per te.


0

Ho provato solo con EditText ma puoi usare il metodo

public void setBackgroundResource (int resid)

per applicare uno stile definito in un file XML.

Sine questo metodo appartiene a View Credo che funzionerà con qualsiasi elemento dell'interfaccia utente.

Saluti.


Secondo la documentazione questo dovrebbe funzionare solo con i disegni, non con lo stile. Quindi, se funziona davvero, è solo "per caso" e non dovresti fare affidamento su di esso.
Heinzi,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.