Freunde, den ganzen Freitag großartig. Wir möchten Ihnen eine Übersetzung eines Artikels mitteilen, der speziell für Studenten des Kurses 
„Android-Entwickler. Fortgeschrittenenkurs . 
“ Gute Lektüre.

So deklarieren Sie Text unter Android deklarativ.
 Virginia Poltrack Illustration
Virginia Poltrack IllustrationTextView in Android-Anwendungen bietet verschiedene Attribute zum Stylen von Text und verschiedene Möglichkeiten, sie anzuwenden. Diese Attribute können direkt im Layout festgelegt werden, einen Stil auf die Ansicht oder das Thema auf das Layout anwenden oder, wenn Sie möchten, textAppearance festlegen. Aber was davon sollte verwendet werden? Und was passiert, wenn Sie sie kombinieren? 
 Was und wann verwenden?
Was und wann verwenden?In diesem Artikel werden verschiedene Ansätze zur deklarativen Stilisierung von Text beschrieben (dh wenn Sie Stile in einer XML-Datei definieren). Außerdem werden Umfang und Priorität der einzelnen Methoden erläutert.
tl; dr;
Sie 
sollten den gesamten Beitrag lesen, aber hier ist eine Zusammenfassung.
Denken Sie an die Prioritätsreihenfolge verschiedener Stilmethoden. Wenn Sie versuchen, Text zu stilisieren und die erwarteten Ergebnisse nicht sehen, werden Ihre Änderungen höchstwahrscheinlich von etwas mit einer höheren Priorität in dieser Hierarchie überschrieben:
 Hierarchie der Textstilmethoden
Hierarchie der TextstilmethodenIch würde das folgende Verfahren für das Styling vorschlagen:
- textViewStyleSie einen beliebigen Anwendungsstil in- textViewStyleals Standardstil für Ihr Thema fest.
- Installieren Sie den (kleinen) Satz von TextAppearance, den Ihre Anwendung verwendet (oder von MaterialComponent- Stilen verwendet / erbt), und verweisen Sie direkt aus Ihrer Ansicht darauf
- Erstellen Sie einen styleindem Sie AttributeTextAppearancedie vonTextAppearancenicht unterstützt werden (die selbst einen IhrerTextAppearance).
- Führen Sie ein einzigartiges Styling direkt im Layout durch.
Zeigen Sie etwas Stil
Sie können die 
TextView Attribute direkt im Layout 
TextView , dieser Ansatz kann jedoch langwieriger und unsicherer sein. Stellen Sie sich vor, Sie versuchen auf diese Weise, die Farbe aller TextViews in der Anwendung zu aktualisieren. Wie bei allen anderen Ansichten können (und sollten!) Sie stattdessen Stile verwenden, um Konsistenz, Wiederverwendung und einfache Aktualisierung sicherzustellen. Zu diesem Zweck empfehle ich, Stile für Text zu erstellen, wenn Sie wahrscheinlich denselben Stil auf mehrere Ansichten anwenden möchten. Dies ist äußerst einfach und wird weitgehend vom Android-Ansichtssystem unterstützt.
Was passiert unter der Haube, wenn Sie die Ansicht stylen? Wenn Sie jemals Ihre benutzerdefinierte Ansicht geschrieben haben, haben Sie wahrscheinlich den Aufruf von 
context.obtainStyledAttributes (AttributeSet, int [], int, int) gesehen . Somit übergibt das Ansichtssystem in Android die im Layout angegebenen Attribute an die Ansicht. Der 
AttributeSet Parameter kann tatsächlich als Zuordnung der XML-Parameter betrachtet werden, die Sie in Ihrem Layout angeben. Wenn das AttributeSet den Stil festlegt, wird der 
Stil zuerst gelesen und dann werden die direkt in der Ansicht angegebenen Attribute darauf angewendet. Damit kommen wir zur ersten Prioritätsregel.
Ansicht → StilDirekt in der Ansicht definierte Attribute "überwiegen" immer und überschreiben die im Stil definierten Attribute. Beachten Sie, dass eine 
Kombination aus Stil- und Ansichtsattributen angewendet wird. Durch das Definieren eines Attributs in der Ansicht, das auch im Stil angegeben ist, 
wird nicht der gesamte Stil abgebrochen. Es sollte auch beachtet werden, dass es Ihrer Ansicht nach keine wirkliche Möglichkeit gibt, festzustellen, woher die Stilisierung kommt. Dies wird vom Ansichtssystem für Sie einmal in einem ähnlichen Anruf entschieden. Sie können nicht beide Optionen erhalten und auswählen.
Obwohl Stile äußerst nützlich sind, haben sie ihre Grenzen. Eine davon ist, dass Sie nur einen Stil auf die Ansicht anwenden können (im Gegensatz zu CSS, bei dem Sie mehrere Klassen anwenden können). 
TextView hat jedoch einen Trick: Es stellt das 
TextAppearance Attribut 
TextAppearance , das ähnlich wie der 
style funktioniert. Wenn Sie Text über 
TextAppearance , lassen Sie das 
TextAppearance für andere Stile frei, was praktisch aussieht. Schauen wir uns genauer an, was 
TextAppearance und wie es funktioniert.
Textauftritt
TextAppearance nichts Magisches (zum Beispiel einen geheimen Modus zum Anwenden mehrerer Stile, über die Sie nichts wissen sollten !!!!). 
TextView erspart Ihnen unnötige Arbeit. Schauen wir uns den 
TextView Konstruktor an, um zu verstehen, was passiert.
 TypedArray a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes); TypedArray appearance = null; int ap = a.getResourceId(com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1); a.recycle(); if (ap != -1) { appearance = theme.obtainStyledAttributes(ap, com.android.internal.R.styleable.TextAppearance); } if (appearance != null) { readTextAppearance(context, appearance, attributes, false); appearance.recycle(); }  
Also, was ist hier los? Im Wesentlichen 
TextView die 
TextView zunächst, ob Sie 
android:textAppearance angegeben haben. In diesem 
android:textAppearance wird dieser Stil 
android:textAppearance und alle dort aufgeführten Eigenschaften werden 
android:textAppearance . Später lädt er alle Attribute aus der Ansicht (an die er sich erinnert, einschließlich des Stils) und wendet sie an. Wir kommen also zur Regel der zweiten Priorität:
Ansicht → Stil → TextdarstellungDa das Erscheinungsbild des Texts zuerst überprüft wird, werden alle Attribute, die entweder direkt in der Ansicht oder im Stil definiert sind, überschrieben.
Bei 
TextAppearance ist noch eine weitere 
TextAppearance zu beachten: Es unterstützt eine 
Teilmenge der 
TextView , die 
TextView bietet. Um besser zu verstehen, was ich meine, gehen wir zurück zu dieser Zeile:
obtainStyledAttributes(ap, android.R.styleable.TextAppearance);Wir haben uns die Version 
receiveStyledAttributes mit 4 Argumenten angesehen. Diese Version mit 2 Argumenten unterscheidet sich geringfügig davon. Sie betrachtet den angegebenen Stil (wie durch die erste Parameter- 
id ) und filtert ihn nur nach den Attributen im Stil, die im zweiten Parameter, dem 
attrs Array, 
attrs . So definiert styleable 
android.R.styleable.TextAppearance den Umfang der 
TextAppearance . Wenn wir uns diese Definition ansehen, 
TextAppearance wir, dass 
TextAppearance viele, 
aber nicht alle Attribute 
unterstützt , die 
TextView unterstützt .
 <attr name="textColor" /> <attr name="textSize" /> <attr name="textStyle" /> <attr name="typeface" /> <attr name="fontFamily" /> <attr name="textColorHighlight" /> <attr name="textColorHint" /> <attr name="textColorLink" /> <attr name="textAllCaps" format="boolean" /> <attr name="shadowColor" format="color" /> <attr name="shadowDx" format="float" /> <attr name="shadowDy" format="float" /> <attr name="shadowRadius" format="float" /> <attr name="elegantTextHeight" format="boolean" /> <attr name="letterSpacing" format="float" /> <attr name="fontFeatureSettings" format="string" /> 
Von TextAppearance unterstützte Styling-AttributeHier sind einige 
TextView Attribute, die nicht in 
TextAppearance : 
lineHeight[Multiplier|Extra] , 
lines , 
breakStrategy und 
breakStrategy . 
TextAppearance funktioniert auf Zeichenebene und nicht auf 
TextAppearance , sodass Attribute, die sich auf das gesamte Layout auswirken, nicht unterstützt werden.
Daher ist 
TextAppearance sehr nützlich. Es ermöglicht uns, einen Stil zu definieren, der sich an den 
TextAppearance orientiert, und lässt den 
style für andere Zwecke frei. Es hat jedoch einen begrenzten Umfang und befindet sich am Ende der Prioritätskette. Vergessen Sie also nicht die Einschränkungen.
Angemessene Standardeinstellungen
Als wir uns angesehen haben, wie die Android-Ansicht Attribute auflöst ( 
context.obtainStyledAttributes ), haben wir es tatsächlich ein wenig vereinfacht. Sie ruft 
theme.obtainStyledAttributes auf (unter Verwendung des aktuellen 
Theme Context 'a). Beim Überprüfen des 
Links wird die zuvor untersuchte Prioritätsreihenfolge angezeigt, und es werden zwei weitere Stellen angezeigt, nach denen er sucht, um Attribute aufzulösen: der Standardstil für die Ansicht und das Thema.
Bei der Bestimmung des Endwerts eines bestimmten Attributs kommen vier Eingabeparameter ins Spiel: 
- Alle Attributwerte in diesem AttributeSet.
- Die im AttributeSet angegebene Stilressource (mit dem Namen "style").
- Der von defStyleAttr und defstyleres angegebene Standardstil
- Grundwerte in diesem Thread.
Styling Priority Order aus der ThemendokumentationWir werden auf die Themen zurückkommen, aber schauen wir uns zuerst die Standardstile an. Was ist dieser Standardstil? Um diese Frage zu beantworten, halte ich es für nützlich, das 
TextView Thema ein wenig zu verlassen und einen einfachen 
Button . Wenn Sie 
< Button > in Ihr Layout einfügen, sieht es ungefähr so aus.
 Standardknopf
StandardknopfWarum? Wenn Sie sich den Quellcode von 
Button ansehen, werden Sie feststellen, dass er eher dürftig ist:
 public class Button extends TextView { public Button(Context context) { this(context, null); } public Button(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.buttonStyle); } public Button(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public CharSequence getAccessibilityClassName() { return Button.class.getName(); } @Override public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) { if (getPointerIcon() == null && isClickable() && isEnabled()) { return PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_HAND); } return super.onResolvePointerIcon(event, pointerIndex); } } 
Das ist alles! Hier ist die ganze Klasse (kein Kommentar). Sie können 
es hier selbst überprüfen. Ich warte. Woher kommen also Hintergrund, Großbuchstaben, Welligkeit usw.? Möglicherweise haben Sie etwas verpasst, aber alles wird im Konstruktor mit zwei Argumenten definiert. Eine, die aufgerufen wird, wenn das Layout aus XML übernommen wird. Dies ist der letzte Parameter, der 
defaultStyleAttr in 
com.android.internal.R.attr.buttonStyle definiert. Dies ist der Standardstil, bei dem es sich im Wesentlichen um einen indirekten Referenzpunkt handelt, mit dem Sie den Standardstil angeben können. Es zeigt nicht direkt auf den Stil, sondern ermöglicht es Ihnen, auf einen der in Ihrem Thema angegebenen Stile zu verweisen, die beim Auflösen von Attributen überprüft werden. Und genau das tun alle Themen, von denen Sie normalerweise erben, um das Erscheinungsbild von Standard-Widgets zu erhalten. Wenn Sie sich beispielsweise das Thema Material ansehen, definiert es 
@style/Widget.Material.Light.Button , und dieser Stil bietet alle Attribute, die 
theme.obtainStyledAttributes wenn Sie nichts anderes angegeben haben.
Zurück zu 
TextView bietet es auch einen Standardstil: 
textViewStyle . Dies kann sehr praktisch sein, wenn Sie einige Stile auf jede Textansicht in Ihrer Anwendung anwenden möchten. Angenommen, Sie möchten den Standardzeilenabstand auf 1,2 festlegen. Sie können dies mit 
style/TextAppearance und versuchen, es während einer 
style/TextAppearance (oder vielleicht sogar mit einer eleganten benutzerdefinierten Regel in Lint) anzuwenden. Sie müssen jedoch wachsam sein und sicherstellen, dass Sie neue Teammitglieder einstellen , seien Sie vorsichtig beim Refactoring usw.
Ein besserer Ansatz wäre, Ihren eigenen Standardstil für alle 
TextView in der Anwendung anzugeben und das gewünschte Verhalten 
TextView . Sie können dies tun, indem Sie Ihren eigenen Stil für 
textViewStyle , der standardmäßig von der Plattform oder von 
MaterialComponents/AppCompat wird.
 <style name="Theme.MyApp" parent="@style/Theme.MaterialComponents.Light"> ... <item name="android:textViewStyle">@style/Widget.MyApp.TextView</item></style> <style name="Widget.MyApp.TextView" parent="@android:style/Widget.Material.TextView"> <item name="android:textAppearance">@style/TextAppearance.MyApp.Body</item> <item name="android:lineSpacingMultiplier">@dimen/text_line_spacing</item> </style> 
In diesem Sinne hat unsere Prioritätsregel die Form:
Ansicht -> Stil -> Standardstil -> TextdarstellungIm Rahmen der Auflösung der Attribute des Ansichtssystems wird dieser Slot nach den Stilen ausgefüllt (sodass standardmäßig alles im Stil durch den angewendeten Stil oder die Ansichtsattribute gelöscht wird), überschreibt jedoch weiterhin das Erscheinungsbild des Texts. Standardstile können sehr praktisch sein. Wenn Sie sich jemals dazu entschließen, eine eigene benutzerdefinierte Ansicht zu schreiben, können diese eine leistungsstarke Methode zum Implementieren des Standardverhaltens sein und das Anpassen vereinfachen.
Wenn Sie das Widget erben und keinen eigenen Standardstil angeben, müssen Sie den Standardstil der übergeordneten Klasse in den Konstruktoren verwenden (übergeben Sie nicht nur 0). Wenn Sie beispielsweise von 
AppCompatTextView erben und Ihren eigenen Konstruktor mit 2 Argumenten schreiben, müssen Sie 
android.R.attr.textViewStyle defaultStyleAttr ( 
wie hier ) übergeben, da Sie sonst das Verhalten der übergeordneten Klasse verlieren.
Themen
Wie bereits erwähnt, gibt es eine andere (ich verspreche es letzte) Möglichkeit, Styling-Informationen bereitzustellen. Ein anderer Ort 
theme.obtainStyledAttributes wird direkt in das Thema selbst schauen. Das heißt, wenn Sie Ihrem Thema ein 
android:textColor hinzufügen, z. B. 
android:textColor , 
android:textColor das Ansichtssystem es als letzten Ausweg aus. In der Regel ist es eine schlechte Idee, Themenattribute und Stilattribute zu mischen. Das heißt, was Sie direkt auf die Ansicht anwenden, sollte in der Regel niemals für das Thema festgelegt werden (und umgekehrt), aber es gibt einige seltene Ausnahmen.
Ein Beispiel wäre, wenn Sie versuchen, die Schriftart in der gesamten Anwendung zu ändern. Sie können eine der oben beschriebenen Methoden verwenden, aber das manuelle Anpassen der Stile / des Erscheinungsbilds des Texts überall ist eintönig und unsicher, und die Standardstile funktionieren nur auf Widget-Ebene. Unterklassen können dieses Verhalten überschreiben. Beispielsweise definieren Schaltflächen ihren eigenen 
android:buttonStyle , den Ihr 
android:textViewStyle nicht 
android:textViewStyle . Stattdessen können Sie die Schriftart in Ihrem Thema angeben:
 <style name="Theme.MyApp" parent="@style/Theme.MaterialComponents.Light"> ... <item name="android:fontFamily">@font/space_mono</item> </style> 
Jetzt nimmt jede Ansicht, die dieses Attribut unterstützt, es auf, wenn es nicht von etwas mit einer höheren Priorität überschrieben wird:
Ansicht → Stil → Standardstil → Thema → TextdarstellungDa dies wiederum Teil des Ansichtsstilsystems ist, überschreibt es alles, was in Textform bereitgestellt wird, wird jedoch durch spezifischere Attribute überschrieben.
Denken Sie an diese Priorität. In unserem Beispiel mit einer Schriftart für die gesamte Anwendung können Sie erwarten, dass die 
Toolbar diese Schriftart 
TextView , da sie den Titel enthält, bei dem es sich um eine 
TextView . Die Toolbar-Klasse selbst definiert jedoch einen Standardstil mit 
titleTextAppearance , der 
android:fontFamily definiert, und legt ihn direkt im 
TextView Header fest, wobei der Wert auf 
TextView überschrieben wird. Stile auf Themenebene können nützlich sein, lassen sich jedoch leicht überschreiben. Stellen Sie daher sicher, dass sie ordnungsgemäß angewendet werden.
Bonus: Ungelöste Probleme
Dieser gesamte Artikel widmete sich der deklarativen Gestaltung von Text auf Ansichtsebene, 
TextView dem Stil der gesamten 
TextView während des Füllens. Jeder nach dem Füllen angewendete Stil (z. B. 
textView.setTextColor(…) ) überschreibt das deklarative Styling. 
TextView unterstützt auch kleinere Stile über 
Span . Ich werde nicht auf dieses Thema eingehen, da es in Artikeln von 
Florina Muntenescu ausführlich beschrieben wird.
→ 
Spantastisches Textstyling mit Spans→ 
Überspannende BereicheIch werde dies der Vollständigkeit halber erwähnen, um zu berücksichtigen, dass Programmstil und -spannen ganz oben auf der Prioritätsreihenfolge stehen:
Bereich → Setter → Ansicht → Stil → Standardstil → Thema → TextdarstellungWählen Sie Ihren Stil
Obwohl es verschiedene Möglichkeiten gibt, Ihren Text zu formatieren, hilft Ihnen das Verständnis der Unterschiede zwischen Methoden und ihrer Einschränkungen, das richtige Werkzeug für eine bestimmte Aufgabe zu finden oder zu verstehen, warum eine Methode Vorrang vor einer anderen hat.
Habt einen schönen Text Styling!
Wir laden alle zu einem 
kostenlosen Webinar ein, in dessen Rahmen wir uns mit dem DI-Framework Dagger 2 vertraut machen werden: Wir werden untersuchen, wie Dagger2 Code generiert, wir werden mit JSR 330-Annotationen und Dagger2-Konstrukten umgehen, wir werden lernen, wie Dagger2 in einer Multimodul-Anwendung verwendet wird, und den Dagger Android Injector in Betracht ziehen.