Legen Sie den Stil für TextView programmgesteuert fest


249

Ich versuche das zu benutzen TextView Konstruktor mit einem Stil wie diesem zu verwenden:

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

Wenn ich dies tue, scheint die Textansicht jedoch nicht den Stil zu übernehmen (ich habe den Stil überprüft, indem ich ihn für ein statisches Objekt festgelegt habe).

Ich habe es auch versucht, myText.setTextAppearance(MyActivity.this, R.style.my_style)aber es funktioniert auch nicht.

Antworten:


318

Ich glaube nicht, dass Sie den Stil programmatisch festlegen können. Um dies zu umgehen, können Sie eine XML-Datei mit Vorlagenlayout mit dem zugewiesenen Stil erstellen, z. B. in res / layout create tvtemplate.xml mit dem folgenden Inhalt:

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

Blasen Sie dies dann auf, um Ihre neue Textansicht zu instanziieren:

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

Hoffe das hilft.


1
Die Antwort von Dandre Allison ist, dass API v11 nicht erforderlich ist.
Martin Capodici

2
Es könnte funktioniert haben, aber das macht keinen Sinn. Wie kann es möglicherweise mit der XML-Datei eingestellt werden? wenn nicht programmgesteuert . Es gibt Gründe, keine XML-Dateien zu verwenden. Einer davon ist, dass ich Code zum Erstellen der Benutzeroberfläche schreibe, damit ich keine neue Methode erlernen möchte, da mein Speicher begrenzt ist und ich etwas Platz dafür haben möchte andere Dinge.
Iharob Al Asimi

@IharobAlAsimi das stimmt, alles kann programmgesteuert erledigt werden, und LayoutInflater weiß alles darüber, wie man XML in Objekte verwandelt. Leider sind viele dieser Dinge unter privaten APIs verborgen, und die einzige Möglichkeit, einige Objekte zu erstellen, besteht darin, dem Konstruktor AttributeSet bereitzustellen.
Miha_x64

Im Gegensatz zu allen anderen Antworten funktionierte dies tatsächlich mit Spinnern, also ein goldener Stern für Sie
Rowan Berry

121

Sie können einen generischen Stil erstellen und ihn in mehreren Textansichten wie der folgenden wiederverwenden:

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

Bearbeiten: Dies bezieht sich auf den Kontext


50
Ihre Antwort funktioniert, solange Sie nur mit dem "Stil" des Textes herumtollen. Es funktioniert nicht, wenn Sie versuchen, andere Dinge mit der Textansicht zu tun, z. B. Auffüllen oder Ränder hinzufügen. Ich sage also nicht, dass Sie falsch liegen, aber Ihre Antwort ist begrenzt. Das Aufblasen der Ansicht zur Laufzeit ist die einzige Möglichkeit, einen umfassenden Stil anzuwenden.
Bill Mote

1
Beide Lösungen zur Verwendung einer aufgeblasenen Vorlage und zur Verwendung von setTextAppearance sind sinnvoll. Um das Problem des Auffüllens / Randes für die 2. Lösung zu beheben, können Sie textView.setLayoutParams (layoutParams)
AlanKley

Diese Methode wurde in API-Ebene 23 nicht mehr unterstützt. Verwenden Sie stattdessen setTextAppearance (int) in API 23+.
Sergii


4
Verwenden Sie die Methode aus der Support-Bibliothek,TextViewCompat.setTextAppearance
Rubin Yoo

97

Sie können einen ContextThemeWrapper wie folgt an den Konstruktor übergeben:

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

1
tolles Zeug! Nur so konnte ich Stile programmgesteuert festlegen, während ich API 8 unterstützte.
tbraun

Aus irgendeinem Grund hat dies keinen Einfluss auf den Stil meiner Schaltfläche. Ich habe meinen Stil wie folgt definiert : <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. Und dann rufe ich es mit einer Konstruktion auf : new Button(new ContextThemeWrapper(context, R.style.TabButton));. Aber die Schaltfläche ignoriert einfach meine Einstellungen. Mache ich hier etwas falsch?
Aleks N.

@ AlaksiejN.You sollte von Widget.Button-Stil wie diesem erbenparent="@android:style/Widget.Button"
maxcanna

@maxcanna Aus irgendeinem Grund hat sich das Hinzufügen parentnicht geändert. Also habe ich einfach die inflateLösung gemacht.
Aleks N.

11
@AliakseiN. Sie müssen den 3-Argument-Konstruktor verwenden, z new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). Andernfalls wird der Standardschaltflächenstil angewendet, und dieser Stil überschreibt den Schaltflächenstil, den Sie über den ContextThemeWrapper in das Thema eingefügt haben.
Newtonx

17

Sie können den Stil im Konstruktor festlegen (Stile können jedoch nicht dynamisch geändert / festgelegt werden).

View(Context, AttributeSet, int)(Das intist ein Attribut im aktuellen Thema, das einen Verweis auf einen Stil enthält.)

Antwort von Romain Guy

Referenz


Ihre Antwort ist irreführend - haben Sie versucht, diesen Thread bis zum Ende zu lesen?
andr

3
Wie ist es irreführend? Die akzeptierte Antwort ist irreführend, da Romain Guy ausdrücklich sagt, dass Sie einen Stil programmgesteuert "festlegen" können. Es gibt einfach keine Möglichkeit, dies dynamisch zu ändern. Dieser Thread scheint jedoch nicht zu glauben, dass dies der Fall ist.
Dandre Allison

1
Achtung, dieser Aufruf erfordert API Level 11.
Martin Capodici

1
@PaulVerest es ist kein Zitat.
Dandre Allison

6
Das letzte int ist keine Stilressource. Es ist "Ein Attribut im aktuellen Thema, das einen Verweis auf eine Stilressource enthält, die Standardwerte für die Ansicht bereitstellt."
rve

11

Der Parameter int defStyleAttrgibt den Stil nicht an. Aus der Android-Dokumentation:

defStyleAttr - Ein Attribut im aktuellen Design , das einen Verweis auf eine Stilressource enthält, die Standardwerte für die Ansicht bereitstellt . Kann 0 sein, um nicht nach Standardeinstellungen zu suchen.

Um den Stil im View-Konstruktor einzurichten, haben wir zwei mögliche Lösungen:

  1. Bei Verwendung von ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
  2. Mit Konstruktor mit vier Argumenten (verfügbar ab LOLLIPOP):

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

Schlüsselsache für beide Lösungen - defStyleAttrParameter sollte 0 sein, um unseren Stil auf die Ansicht anzuwenden.


5

Dynamisch wechselnde Stile werden (noch) nicht unterstützt. Sie müssen den Stil festlegen, bevor die Ansicht über XML erstellt wird.


20
das ist eigentlich das gleiche
njzk2

@ njzk2 danke ... habe offensichtlich vor dem Posten nicht über seinen Kommentar nachgedacht. Es gibt keine Möglichkeit, den Stil programmgesteuert festzulegen, bevor die Benutzeroberfläche erstellt wird. Daher wird derselbe Code verwendet, um den Stil programmgesteuert zu ändern oder festzulegen.
Chris Cashwell

3

Die akzeptierte Antwort war eine großartige Lösung für mich. Das einzige, was hinzugefügt werden muss, ist die inflate()Methode.

In der akzeptierten Antwort android:layout_*werden nicht alle Parameter angewendet.

Der Grund ist keine Möglichkeit, es anzupassen, Ursache nullwurde als übergeben ViewGroup parent.

Sie können es so verwenden:

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

und das parentist das ViewGroup, von wo aus du dich gerne einstellst android:layout_*.

In diesem Fall werden alle relativen Eigenschaften festgelegt.

Hoffe, es wird für jemanden nützlich sein.


2

Wenn Sie benutzerdefinierte Ansichten verwenden, die möglicherweise die Stilvererbung (oder ereignisstilfähige Attribute) verwenden, müssen Sie den zweiten Konstruktor ändern, um den Stil nicht zu verlieren. Dies funktionierte bei mir, ohne dass setTextAppearence () verwendet werden musste :

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

2

Ich bin auch auf das Problem gestoßen und habe den Weg gefunden, den Stil programmatisch festzulegen. Vielleicht braucht ihr es alle, also aktualisiere ich dort.

Der dritte Parameter des View-Konstruktors akzeptiert einen Typ von attr in Ihrem Design als folgenden Quellcode:

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

Sie müssen also eine Art von R.attr. ** anstelle von R.style. ** übergeben

In meinen Codes habe ich folgende Schritte ausgeführt:

Passen Sie zunächst ein benutzerdefiniertes attr an, das von Themen in attr.xml verwendet werden soll.

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

Zweitens geben Sie Ihren Stil in Ihrem verwendeten Thema in style.xml an.

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

Am Ende benutze es!

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

Die programmgesteuert erstellte Ansicht verwendet den angegebenen Stil in Ihrem Thema.

Sie können es versuchen und hoffen, dass es perfekt für Sie funktioniert.


0

Ich habe nur mit EditText getestet, aber Sie können die Methode verwenden

public void setBackgroundResource (int resid)

um einen in einer XML-Datei definierten Stil anzuwenden.

Da diese Methode zu View gehört, funktioniert sie meiner Meinung nach mit jedem UI-Element.

Grüße.


Laut Dokumentation sollte dies nur mit Drawables funktionieren, nicht mit Style. Wenn dies also wirklich funktioniert, ist es nur "zufällig" und Sie sollten sich nicht darauf verlassen.
Heinzi

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.