Fast alle Entwickler wissen, dass es Themen im Android gibt, aber ihre Verwendung beschränkt sich normalerweise auf das Kopieren von XML-Teilen aus Stack Overflow oder anderen Ressourcen. Es gibt Informationen im Internet zu Themen, aber dies ist normalerweise nur ein Rezept, um ein bestimmtes Ergebnis zu erzielen. In diesem Artikel habe ich versucht, einen einführenden Überblick über den Android-Stilisierungsmechanismus zu geben.
Inhalt
EinführungAttribute für RectViewStil für RectViewStandardstilRectView Style Theme-AttributAktivitätslevel-ThemaThema anzeigenSo wenden Sie Attributwerte anRessourcenthemenZusammenfassungEinführung
Stile und Designs in Android sind Mechanismen, mit denen Sie die Designdetails (z. B. Farbe, Schriftgröße usw.) von der Struktur der Benutzeroberfläche trennen können. Um zu verstehen, wie dies funktioniert, hilft uns ein einfaches Beispiel mit benutzerdefinierter Ansicht.
Wir benötigen eine einfache benutzerdefinierte Ansicht, die ein Rechteck mit der gewünschten Farbe innerhalb der Grenzen der Ansicht zeichnet.
class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } }

Attribute für RectView
Jetzt möchte ich die Farbe des Layout-Rechtecks ändern können.
Dazu müssen wir ein neues Attribut hinzufügen und der Datei attrs.xml hinzufügen
<resources> <attr name="rectColor" format="color"/> </resources>
Jetzt können wir im Code über R.attr.rectColor und auf die ID dieses Attributs zugreifen
Im Layout des Bildschirms können wir das Attribut app: rectColor verwenden.
<org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" app:rectColor="@color/colorPrimary" android:layout_height="100dp"/>
RectView weiß jedoch noch nicht, dass es ein Attribut gibt, mit dem Sie die Farbe für das Rechteck übernehmen können.
Lassen Sie uns RectView beibringen, das rectColor-Attribut zu verstehen, und eine Gruppe von Attributen hinzufügen
<resources> <attr name="rectColor" format="color"/> <declare-styleable name="RectView"> <attr name="rectColor"/> </declare-styleable> </resources>
In der Klasse R wurden 2 neue Felder generiert:
R.styleable.RectView ist ein Array von ID-Attributen. Derzeit ist es ein Array von einem Element R.attr.rectColor
R.styleable.RectView_rectColor ist der ID-Index des Attributs im R.styleable.RectView-Array, d. H. ID-Attribut, das wir bekommen können und so R.styleable.RectView [R.styleable.RectView_rectColor]
Fügen Sie dem Code Unterstützung für das Attribut rectColor hinzu.
init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } }
Vollständiger Code class RectView @JvmOverloads constructor( context: Context, attrSet: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrSet, defStyleAttr) { private val paint = Paint().apply { color = Color.BLUE } init { val typedArray = context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, 0 ) try { paint.color = typedArray.getColor( R.styleable.RectView_rectColor, Color.BLUE ) } finally { typedArray.recycle() } } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } }
Jetzt können wir die Farbe des Rechtecks im Layout ändern:

Stil für RectView
Jetzt haben wir nur ein Attribut, aber nehmen wir an, es gibt zehn davon - es wäre äußerst unpraktisch für uns, jedes Mal alle diese Attribute im Layout für ähnliche Elemente festzulegen.
Die Entscheidung, alles mit Stil zu machen.
<style name="DefaultRectViewStyle"> <item name="rectColor">@color/colorAccent</item> </style>
Jetzt können wir jede Art von Ansicht mit demselben Erscheinungsbild erstellen, indem wir den Stil angeben.
<org.berendeev.themes.RectView android:id="@+id/text2" android:layout_width="100dp" style="@style/DefaultRectViewStyle" android:layout_height="100dp"/>
Standardstil
Jetzt möchten wir, dass alle Ansichten standardmäßig einen Stil haben. Dazu geben wir den Standardstil für die Methode receiveStyledAttributes an:
context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, 0, R.style.DefaultRectViewStyle )
Das ist genug. Jetzt haben alle RectViews, die wir dem Layout hinzufügen, den Standardstil DefaultRectViewStyle.
RectView Style Theme-Attribut
Der Standardwert ist gut, aber ich möchte das Layout flexibler steuern. Es ist praktisch, den Stil einer bestimmten Ansicht für die gesamte Anwendung oder für eine separate Aktivität festzulegen.
Dafür brauchen wir ein neues Attribut. Wir werden seinen Wert im Thema festlegen. Der Wert ist der Stil, der das Erscheinungsbild von RectView bestimmt.
<attr name="rectViewStyle" format="reference"/>
Und bringen Sie unserem rectView bei, dieses Themenattribut zu verstehen. Durch Übergeben des dritten Parameters R.attr.rectViewStyle an die Methode receiveStyledAttributes.
context.theme.obtainStyledAttributes( attrSet, R.styleable.RectView, R.attr.rectViewStyle, R.style.DefaultRectViewStyle )
Wenn nun ein Element mit dem Namen rectViewStyle und einem Wert vom Typ style im Thema angegeben ist, gilt dieser Stil für alle RectView mit diesem Thema.
Aktivitätslevel-Thema
Wir legen den Wert des Attributs rectViewStyle in unserem Thema fest.
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style> </resources>
Geben Sie das Thema im Anwendungsmanifest an.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.berendeev.themes"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
Alle Aktivitäten werden auf das Standard-AppTheme-Design eingestellt. Wir legen das RectView-Design für die gesamte Anwendung fest.
Das Thema kann auch für eine bestimmte Aktivität im Manifest festgelegt werden.
<activity android:name=".MainActivity" android:theme="@style/MyTheme">
Hierbei ist es wichtig, dass das Thema, das wir auf Anwendungs- oder Aktivitätsebene festlegen, vom Standardthema geerbt wird. Zum Beispiel Theme.AppCompat. Andernfalls kommt es zur Laufzeit zum Absturz.
java.lang.IllegalStateException: Für diese Aktivität müssen Sie ein Theme.AppCompat-Design (oder einen Nachkommen) verwenden.
Thema anzeigen
Auf Ansichtsebene installieren wir das Design nicht erneut, sondern überschreiben die gewünschten Attributwerte, sodass wir nicht vom Standarddesign erben müssen. Ein übergeordnetes Element kann leer sein, oder wir können beispielsweise von einem der ThemeOverlay.AppCompat-Overlays erben.
Hier legen wir das MyOverlay-Thema für die LinearLayout-Gruppe und alle ihre Nachkommen in der Hierarchie fest.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:theme="@style/MyOverlay"> <org.berendeev.themes.RectView android:layout_width="100dp" android:layout_height="100dp"/> </LinearLayout>
In dem Fach können wir auf einen Elternteil verzichten, weil Wir ändern nur das Aktivitätsthema.
<style name="MyOverlay"> <item name="rectViewStyle">@style/LocalRectViewStyle</item> </style>
So wenden Sie Attributwerte an

Wenn wir für die Ansicht die Attributwerte sowohl im Layout als auch im Stil und im Thema definieren, lautet die Reihenfolge der Auswahl des Werts wie folgt. Die höchste Priorität ist der im Layout angegebene Wert, d. H. Wenn der Wert im Layout festgelegt ist, werden Stil und Thema ignoriert, dann wird der Stil fortgesetzt, dann das Thema und zuletzt der Standardstil.
Ressourcenthemen
Themenwerte können in Ressourcen verwendet werden. In Drawable können wir beispielsweise eine Farbe festlegen, die von der im Thema festgelegten Farbe abhängt.
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="?attr/colorPrimary"/> </shape>
Jetzt hängt die Farbe des Rechtecks vom Wert des colorPrimary-Attributs im Thema ab. Das Attribut kann ein beliebiges sein. Zum Beispiel können wir unser Attribut in Ressourcen festlegen und seinen Wert im Betreff festlegen.
Ein solcher Trick kann in allen Ressourcen verwendet werden, beispielsweise im Selektor oder beim Vektorzeichnen. Dies macht das Design strukturierter und flexibler. Wir können das Thema für alle Aktivitäten schnell ändern.
Zusammenfassung
- Das Thema und der Stil auf Ressourcenebene sind ein und dasselbe, werden jedoch unterschiedlich verwendet.
- Ein Thema kann andere Themen enthalten, nur Bedeutungen oder Stile für die Ansicht.
- Der Stil wird im Layout auf Ansichtsebene angezeigt. LayoutInflater berechnet die Stilwerte und übergibt sie als AttributeSet an den View-Konstruktor.
- Themen ist ein Mechanismus, mit dem Sie das Erscheinungsbild für die gesamte Aktivität global definieren können.
- Die Themenwerte können für das Element (und die Nachkommen) in der Ansichtshierarchie geändert werden.
- Die Themenwerte können nicht nur in der Ansicht, sondern auch in Ressourcen verwendet werden.
PS: Wenn der Artikel interessant ist, schreibe ich einen fortgeschritteneren Artikel oder einen Artikel mit vielen realen Beispielen.