Définir le style pour TextView par programmation

249

J'essaie d'utiliser le TextViewconstructeur avec un style comme celui-ci:

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

Cependant, lorsque je fais cela, la vue texte ne semble pas prendre le style (j'ai vérifié le style en le plaçant sur un objet statique).

J'ai également essayé d'utiliser myText.setTextAppearance(MyActivity.this, R.style.my_style)mais cela ne fonctionne pas non plus.

Ben
la source

Réponses:

318

Je ne pense pas que vous puissiez définir le style par programmation. Pour contourner cela, vous pouvez créer un fichier xml de mise en page de modèle avec le style attribué, par exemple dans res / layout create tvtemplate.xml comme avec le contenu suivant:

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

puis gonflez-le pour instancier votre nouveau TextView:

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

J'espère que cela t'aides.

Dan Kilpatrick
la source
1
Là où cela gagne la réponse de Dandre Allison, c'est qu'il ne nécessite pas d'API v11.
Martin Capodici
2
Cela a peut-être fonctionné, mais cela n'a aucun sens. Comment peut-il être défini avec le fichier xml? sinon par programmation . Il y a des raisons de ne pas utiliser de fichiers xml, l'un d'eux est que j'ai l'habitude d'écrire du code pour construire l'interface utilisateur, donc je ne veux pas apprendre une nouvelle façon de le faire car ma mémoire est limitée et je veux garder de la place pour autres choses.
Iharob Al Asimi du
@IharobAlAsimi c'est vrai, tout peut être fait par programmation, et LayoutInflater sait tout sur la transformation de XML en objets. Malheureusement, beaucoup de ces choses sont cachées sous des API privées, et la seule façon de créer certains objets est de fournir AttributeSet au constructeur.
Miha_x64
Contrairement à toutes les autres réponses, cela a réellement fonctionné avec les filateurs, donc une étoile d'or pour vous
Rowan Berry
121

Vous pouvez créer un style générique et le réutiliser sur plusieurs vues de texte comme celle ci-dessous:

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

Modifier: cela fait référence au contexte

Shahul3D
la source
50
Votre réponse fonctionne tant que tout ce que vous faites est singe avec le "style" du texte. Cela ne fonctionne pas si vous essayez de faire d'autres choses dans TextView comme ajouter du remplissage ou des marges. Donc, je ne dis pas que vous vous trompez, mais votre réponse est limitée. Gonfler la vue à l'exécution est le seul moyen d'appliquer un style complet.
Bill Mote
1
Les deux solutions d'utilisation d'un modèle gonflé et d'utilisation de setTextAppearance sont raisonnables. Pour résoudre le problème de remplissage / marges pour la 2e solution, vous pouvez appeler textView.setLayoutParams (layoutParams)
AlanKley
Cette méthode est déconseillée dans l'API niveau 23. Utilisez plutôt setTextAppearance (int) dans l'API 23+.
Sergii
Assurez-vous que la version est au moins API 23 (M)
Br0thazS0ul
4
utilisez la méthode de la bibliothèque de support,TextViewCompat.setTextAppearance
Rubin Yoo
97

Vous pouvez passer un ContextThemeWrapper au constructeur comme ceci:

TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));
maxcanna
la source
1
super truc! la seule façon de définir des styles par programmation tout en prenant en charge l'API 8.
tbraun
Pour une raison quelconque, cela n'affecte pas le style de mon bouton. J'ai défini mon style comme: <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. Et puis je l' invoquons avec une construction: new Button(new ContextThemeWrapper(context, R.style.TabButton));. Mais le bouton ignore simplement mes paramètres. Suis-je en train de faire quelque chose de mal ici?
Aleks N.
@ AlaksiejN.Vous devriez hériter du style Widget.Button comme celui-ciparent="@android:style/Widget.Button"
maxcanna
@maxcanna Pour une raison quelconque, l'ajout parentn'a pas changé un peu. Je viens donc d'aller de l'avant avec la inflatesolution.
Aleks N.
11
@AliakseiN. Vous devez utiliser le constructeur 3-arg, par exemple new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). Sinon, le style de bouton par défaut sera appliqué et ce style remplacera le style de bouton que vous avez fusionné dans le thème via ContextThemeWrapper.
Newtonx
17

Vous pouvez définir le style dans le constructeur (mais les styles ne peuvent pas être modifiés / définis dynamiquement).

View(Context, AttributeSet, int)(le intest un attribut du thème actuel qui contient une référence à un style)

Réponse de Romain Guy

référence

Dandre Allison
la source
votre réponse est trompeuse - avez-vous essayé de lire ce fil jusqu'au bout?
andr
3
Comment est-il trompeur? La réponse acceptée est trompeuse, car Romain Guy dit explicitement que vous pouvez "définir" un style par programmation. Il n'y a tout simplement pas de facilité pour le changer dynamiquement. Ce fil ne semble pas penser que ce soit le cas cependant.
Dandre Allison
1
Attention, cet appel nécessite l'API niveau 11.
Martin Capodici
1
@PaulVerest ce n'est pas une citation.
Dandre Allison
6
Le dernier entier n'est pas une ressource de style. Il s'agit d'un "attribut du thème actuel qui contient une référence à une ressource de style qui fournit des valeurs par défaut pour la vue".
rve
11

Le paramètre int defStyleAttrne spécifie pas le style. De la documentation Android:

defStyleAttr - Un attribut dans le thème actuel qui contient une référence à une ressource de style qui fournit des valeurs par défaut pour la vue. Peut être 0 pour ne pas rechercher les valeurs par défaut.

Pour configurer le style dans le constructeur View, nous avons 2 solutions possibles:

  1. Avec l'utilisation de ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
  2. Avec constructeur à quatre arguments (disponible à partir de LOLLIPOP):

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

Élément clé pour les deux solutions - le defStyleAttrparamètre doit être 0 pour appliquer notre style à la vue.

DmitryArc
la source
5

La modification dynamique des styles n'est pas encore prise en charge. Vous devez définir le style avant la création de la vue, via XML.

Chris Cashwell
la source
20
qui se trouve être la même chose, en fait
njzk2
@ njzk2 merci ... n'a évidemment pas pensé à son commentaire avant de poster. Il n'y a aucun moyen de définir le style par programme avant la construction de l'interface utilisateur, donc le même code serait utilisé pour modifier ou définir le style par programme.
Chris Cashwell
3

La réponse acceptée était une excellente solution pour moi. La seule chose à ajouter concerne la inflate()méthode.

Dans la réponse acceptée, tous les android:layout_*paramètres ne seront pas appliqués.

La raison n'est aucun moyen de l'ajuster, la cause a nullété transmise comme ViewGroup parent.

Vous pouvez l'utiliser comme ceci:

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

et le parentest le ViewGroup, d'où vous souhaitez régler android:layout_*.

Dans ce cas, toutes les propriétés relatives seront définies.

J'espère que ce sera utile pour quelqu'un.

Anor
la source
2

Lorsque vous utilisez des vues personnalisées qui peuvent utiliser l'héritage de style (ou des attributs stylables d'événement), vous devez modifier le deuxième constructeur afin de ne pas perdre le style. Cela a fonctionné pour moi, sans avoir besoin d'utiliser setTextAppearence () :

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}
saiyancoder
la source
2

J'ai aussi rencontré le problème et j'ai trouvé le moyen de définir le style par programmation. Peut-être que vous en avez tous besoin, donc je mets à jour là-bas.

Le troisième paramètre du constructeur View accepte un type d'attr dans votre thème comme code source ci-dessous:

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

Vous devez donc passer un type de R.attr. ** plutôt que R.style. **

Dans mes codes, j'ai fait les étapes suivantes:

Tout d'abord, personnalisez un attr personnalisé à utiliser par les thèmes dans attr.xml.

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

Deuxièmement, spécifiez votre style dans votre thème utilisé dans 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>

À la fin, utilisez-le!

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

la vue créée par programmation utilisera le style spécifié dans votre thème.

Vous pouvez essayer et espérer que cela fonctionnera parfaitement pour vous.

mrtwo
la source
0

Je n'ai testé qu'avec EditText mais vous pouvez utiliser la méthode

public void setBackgroundResource (int resid)

pour appliquer un style défini dans un fichier XML.

Sine, cette méthode appartient à View, je crois qu'elle fonctionnera avec n'importe quel élément de l'interface utilisateur.

Cordialement.

floydaddict
la source
Selon la documentation, cela ne devrait fonctionner qu'avec des drawables, pas avec du style. Ainsi, si cela fonctionne vraiment, ce n'est que "par accident" et vous ne devez pas vous y fier.
Heinzi
0

Nous pouvons utiliser TextViewCompact.setTextAppearance(textView, R.style.xyz).

Doc Android pour référence.

Kshitij Jain
la source