Themen und Stile in Android-Apps


Jeder Android-Entwickler musste sowieso mit Stilen arbeiten. Jemand fühlt sich zuversichtlich mit ihnen, jemand hat nur oberflächliches Wissen, was es ihm oft nicht erlaubt, das Problem selbst zu lösen.


Im Vorgriff auf die Veröffentlichung des dunklen Themas wurde beschlossen, alle Informationen zu Themen und Stilen in Android-Anwendungen im Speicher zu aktualisieren.


Was wird diskutiert:


  • Betrachten Sie die grundlegenden Konzepte von Themen und Stilen in Android-Anwendungen und sehen Sie, welche Möglichkeiten sie uns bieten.
  • Lassen Sie uns mithilfe von Materialkomponenten ein einfaches Thema erstellen und mit der Neudefinition von Stilen spielen.
  • Mal sehen, wie das dunkle Thema funktioniert;
  • Formulieren Sie Empfehlungen für die Arbeit mit Stilen.

Beginnen wir mit den Grundlagen


Themen und Stile haben in ihrer Struktur eine gemeinsame Struktur:


<style name="MyStyleOrTheme"> <item name="key">value</item> </style> 

Verwenden Sie zum Erstellen das style Tag. Jeder Stil hat einen Namen und speichert die key-value .


Alles ist ganz einfach. Aber was ist der Unterschied zwischen Thema und Stil?


Der einzige Unterschied ist, wie wir sie verwenden.


Thema


Ein Thema besteht aus einer Reihe von Parametern, die für die gesamte Anwendungs-, Aktivitäts- oder Ansichtskomponente gelten. Es enthält die Grundfarben der Anwendung, Stile zum Rendern aller Komponenten der Anwendung und verschiedene Einstellungen.


Beispielthema:


 <style name="Theme.MyApp.Main" parent="Theme.MaterialComponents.Light.NoActionBar"> <!--Base colors--> <item name="colorPrimary">@color/color_primary</item> <item name="colorPrimaryVariant">@color/color_primary_variant</item> <item name="colorSecondary">@color/color_secondary</item> <item name="colorOnPrimary">@color/color_on_primary</item> <item name="colorOnError">@color/color_on_error</item> <!--Style attributes--> <item name="textAppearanceHeadline1">@style/TextAppearance.MyTheme.Headline1</item> <item name="bottomSheetDialogTheme">@style/ThemeOverlay.MyTheme.BottomSheetDialog</item> <item name="chipStyle">@style/Widget.MaterialComponents.Chip.Action</item> <item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.FilledBox</item> <!--Params--> <item name="android:windowTranslucentStatus">true</item> <!-- ... --> </style> 

Das Thema hat die Hauptfarben der Anwendung ( colorPrimary , colorSecondary ), den Stil für den Text ( textAppearanceHeadline1 ) und einige Standardanwendungskomponenten sowie die Option für eine transparente Statusleiste neu definiert.


Damit der Stil zu einem echten Thema wird, muss von der Standardimplementierung des Themas geerbt werden (wir werden etwas später über die Vererbung sprechen).


Stil


Ein Stil ist eine Reihe von Parametern zum Stylen einer einzelnen Ansichtskomponente.


Beispielstil für TextInputLayout :


 <style name="Widget.MyApp.CustomTextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.FilledBox"> <item name="boxBackgroundMode">outline</item> <item name="boxStrokeColor">@color/color_primary</item> <item name="shapeAppearanceOverlay">@style/MyShapeAppearanceOverlay</item> </style> 

Attribut


Ein Attribut ist ein Stil- oder Themenschlüssel. Dies sind kleine Steine, aus denen alles gebaut ist:


 colorPrimary colorSecondary colorOnError boxBackgroundMod boxStrokeColor shapeAppearanceOverlay ... 

Alle diese Schlüssel sind Standardattribute.


Wir können unsere eigenen Attribute erstellen:


 <attr name="myFavoriteColor" format="color|reference" /> 

Das Attribut myFavoriteColor zeigt auf eine Farbe oder einen Link zu einer myFavoriteColor .


Im Format können wir ganz Standardwerte angeben:


  • Farbe
  • Referenz
  • Zeichenfolge
  • Aufzählung
  • Fraktion
  • Dimension
  • Boolescher Wert
  • Flaggen
  • float
  • Ganzzahl

Ein Attribut ist von Natur aus eine Schnittstelle . Es muss im Thema implementiert werden:


 <style name="Theme.MyApp.Main" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- ... --> <item name="myFavoriteColor">@color/color_favorite</item> </style> 

Jetzt können wir uns darauf beziehen. Die allgemeine Struktur der Berufung sieht folgendermaßen aus:



 1 —   ,     ; 2 — namespace   (   Material Components Library); 3 —   ,     (); 4 —  . 

Nun, zum Schluss ändern wir zum Beispiel die Textfarbe des Feldes:


 <androidx.appcompat.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="?attr/myFavoriteColor"/> 

Dank der Attribute können wir jede Art von Abstraktion hinzufügen, die sich innerhalb des Themas ändert.


Themen und Stile erben


Wie in OOP können wir die Funktionalität einer vorhandenen Implementierung übernehmen. Es gibt zwei Möglichkeiten, dies zu tun:


  • Explizit (explizit)
  • Implizit (implizit)

Für die explizite Vererbung geben wir das übergeordnete Element mit dem parent Schlüsselwort an:


 <style name="SnackbarStyle" parent="Widget.MaterialComponents.Snackbar"> <!-- ... --> </style> 

Für die implizite Vererbung verwenden wir die dot-notation , um das übergeordnete dot-notation anzugeben:


 <style name="SnackbarStyle.Green"> <!-- ... --> </style> 

Es gibt keinen Unterschied in der Arbeit dieser Ansätze.


Sehr oft können wir ähnliche Stile treffen:


 <style name="Widget.MyApp.Snackbar" parent="Widget.MaterialComponents.Snackbar"> <!-- ... --> </style> 

Es scheint, dass der Stil durch doppelte Vererbung erstellt wird. Dies ist eigentlich nicht der Fall. Mehrfachvererbung ist verboten. In dieser Definition gewinnt immer die explizite Vererbung .


Das heißt, ein Stil wird mit dem Namen Widget.MyApp.Snackbar , der der Nachkomme von Widget.MaterialComponents.Snackbar .


Themeoverlay


ThemeOverlay - Dies sind spezielle "Lightweight" -Themen, mit denen Sie die Attribute des Hauptthemas für die View-Komponente überschreiben können .


Wir werden für ein Beispiel nicht weit gehen, sondern einen Fall aus unserer Bewerbung nehmen. Die Designer haben entschieden, dass wir ein Standard-Anmeldefeld erstellen müssen, dessen Farbe sich vom Hauptstil unterscheidet.


Beim Hauptthema sieht das Eingabefeld folgendermaßen aus:



Es sieht gut aus, aber die Designer bestehen darauf, dass das Feld braun ist.


Okay, wie können wir dieses Problem lösen?


  • Stil überschreiben?


    Ja, wir können den Stil neu definieren und die Hauptfarben der Ansicht manuell ändern, aber dafür müssen Sie viel Code schreiben, und es besteht die Möglichkeit, dass wir etwas vergessen.

  • Schreiben Sie Ihre Meinung zu Richtlinien und mit benutzerdefinierten Parametern?


    Eine gute Option, damit wir jede Wunschliste von Designern befriedigen und gleichzeitig die Fähigkeiten des Pumpens verbessern können. All dies ist jedoch mühsam und kann zu unerwünschten Fehlern führen.

  • Hauptfarbe im Thema überschreiben?


    Wir haben herausgefunden, dass für den Typ, den wir benötigen, einfach das colorPrimary im Thema colorPrimary . Eine funktionierende Option, aber auf diese Weise werden wir das Erscheinungsbild der verbleibenden Komponenten beeinflussen, aber wir brauchen es nicht.


Die richtige Lösung ist die Verwendung von ThemeOverlay .


Erstellen Sie ThemeOverlay und definieren Sie die Hauptfarbe des Themas neu :


 <style name="ThemeOverlay.MyApp.Login" parent="ThemeOverlay.MaterialComponents.TextInputEditText"> <item name="colorPrimary">@color/colorBrown</item> </style> 

Als nächstes geben wir es mit dem speziellen android:theme Tag in unserem TextInputLayout :


 <com.google.android.material.textfield.TextInputLayout android:theme="@style/ThemeOverlay.MyApp.Login" android:hint="Login" ... > <com.google.android.material.textfield.TextInputEditText ... /> </com.google.android.material.textfield.TextInputLayout> 

Alles funktioniert wie wir brauchen.



Natürlich stellt sich die Frage: Wie funktioniert das unter der Haube?


Mit dieser Magie können Sie ContextThemeWrapper . Beim Erstellen einer Ansicht in LayoutInflater wird ein Kontext erstellt, in dem das aktuelle Thema als Grundlage verwendet wird und die in unserem Überlagerungsthema angegebenen Parameter darin neu definiert werden.


 ../LayoutInflater.java final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); final int themeResId = ta.getResourceId(0, 0); if (themeResId != 0) { context = new ContextThemeWrapper(context, themeResId); } ta.recycle(); 

Ebenso können wir jeden Themenparameter in der Anwendung unabhängig überschreiben.


Die Reihenfolge, in der Themen und Stile auf die Ansichtskomponente angewendet werden



  1. Die Hauptpriorität ist die Markup-Datei. Wenn darin ein Parameter definiert ist, werden alle ähnlichen Parameter ignoriert.


     <Button android:textColor="@color/colorRed" ... /> 

  2. Die nächste Priorität ist der Ansichtsstil:


     <Button style=“@Widget.MyApp.ButtonStyle" ... /> 

  3. Im Folgenden werden vordefinierte Stile für die Komponente verwendet:


     <style name="Theme.MyApp.Main" parent="Theme..."> <item name=“materialButtonStyle”>@Widget.MyApp.ButtonStyle</item> <!-- ... --> </style> 

  4. Wenn keine Parameter gefunden wurden, werden die Themenattribute verwendet:


     <style name="Theme.MyApp.Main" parent="Theme..."> <item name=“colorPrimary”>@colorPrimary</item> <!-- ... --> </style> 


Im Allgemeinen ist dies alles, was Sie wissen müssen, um mit Themen zu arbeiten. Lassen Sie uns nun einen kurzen Blick auf die aktualisierte Designbibliothek für Materialkomponenten werfen.


Mögen Materialkomponenten mit uns kommen


Material Components wurde auf der Google I / O 2018 vorgestellt und ersetzt die Design Support Library.


Die Bibliothek bietet uns die Möglichkeit, aktualisierte Komponenten aus Material Design 2.0 zu verwenden. Darüber hinaus wurden viele interessante Anpassungsoptionen angezeigt. All dies ermöglicht es Ihnen, helle und einzigartige Anwendungen zu schreiben.




Hier sind einige Beispiele für Anwendungen im neuen Stil: Owl , Reply , Crane .


Lass uns weiter üben


Um ein Thema zu erstellen, müssen Sie vom Basisthema erben:


 Theme.MaterialComponents Theme.MaterialComponents.NoActionBar Theme.MaterialComponents.Light Theme.MaterialComponents.Light.NoActionBar Theme.MaterialComponents.Light.DarkActionBar Theme.MaterialComponents.DayNight Theme.MaterialComponents.DayNight.NoActionBar Theme.MaterialComponents.DayNight.DarkActionBar 

Alle sind AppCompat Designs sehr ähnlich, AppCompat jedoch über zusätzliche Attribute und Einstellungen.


Weitere Informationen zu den neuen Attributen finden Sie unter material.io .


Wenn Sie aus irgendeinem Grund derzeit nicht zu einem neuen Thema wechseln können, sind Bridge Themen ausreichend. Sie erben von AppCompat Designs und verfügen über alle neuen Materialkomponentenattribute. Sie müssen nur das Bridge Postfix hinzufügen und alle Funktionen ohne Angst nutzen:


 <!-- ... --> Theme.MaterialComponents.Light.Bridge <!-- ... --> 

Und hier ist unser Thema:


 <style name="Theme.MyApp.Main" parent="Theme.MaterialComponents.Light.NoActionBar"> <item name="colorPrimary">@color/color_primary</item> <item name="colorPrimaryVariant">@color/color_primary_variant</item> <item name="colorSecondary">@color/color_secondary</item> <item name="colorSecondaryVariant">@color/color_secondary_variant</item> <style> 

Die Namen der Primärfarben (Markenfarben) haben sich geändert:


 colorPrimary —       (   AppCompat); colorPrimaryVariant —    ( colorPrimaryDark  AppCompat); colorSecondary —        ( colorAccent  AppCompat); colorSecondaryVariant —   . 

Weitere Informationen zu Farben finden Sie unter material.io .


Ich habe bereits erwähnt, dass das Thema Standardstile für jede Ansichtskomponente enthält. Für Snackbar Stil beispielsweise snackbarStyle , für checkbox - checkboxStyle und dann ist alles ähnlich. Ein Beispiel wird alles an seinen Platz setzen:



Erstellen Sie Ihren eigenen Stil und wenden Sie ihn auf das Thema an:


 <style name="Theme.MyApp.Main" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- ... --> <item name="snackbarStyle">@style/Widget.MyApp.SnackbarStyle</item> </style> <style name="Widget.MyApp.SnackbarStyle" parent="Widget.MaterialComponents.Snackbar"> <!-- ... --> </style> 

Es ist wichtig zu verstehen, dass ein Stil, der in einem Thema neu definiert wird, für alle Ansichten dieses Typs in der Anwendung (Aktivität) gilt.


Wenn Sie den Stil nur auf eine bestimmte Ansicht anwenden möchten, müssen Sie das style Tag in der Datei mit dem Markup verwenden:


  <com.google.android.material.button.MaterialButton style="@style/Widget.MyApp.SnackbarStyle" ... /> 

Eine der Innovationen, die mich wirklich beeindruckt haben, war ShapeAppearance . Damit können Sie die Form der Komponenten direkt im Motiv ändern!


Jede View-Komponente gehört zu einer bestimmten Gruppe:


  • shapeAppearance Kleine Komponente


  • ShapeAppearance Medium- Komponente


  • shapeAppearance Große Komponente



Wie wir aus dem Namen ersehen können, in Gruppen von Ansichten unterschiedlicher Größe.



In der Praxis prüfen:


 <style name="Theme.MyApp.Main" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- ... --> <item name="shapeAppearanceSmallComponent">@style/Widget.MyApp.SmallShapeAppearance</item> </style> <style name="Widget.MyApp.SmallShapeAppearance" parent=“ShapeAppearance.MaterialComponents.SmallComponent”> <item name="cornerFamilyTopLeft">rounded</item> <item name="cornerFamilyBottomRight">cut</item> <item name="cornerSizeTopLeft">20dp</item> <item name="cornerSizeBottomRight">15dp</item> <!--<item name="cornerFamily">cut</item>--> <!--<item name="cornerSize">8dp</item>--> </style> 

Wir haben Widget.MyApp.SmallShapeAppearance für die "kleinen" Komponenten erstellt. Wir haben die obere linke Ecke um 20dp und die untere rechte Ecke um 15dp abgeschnitten.


Erhalten Sie dieses Ergebnis:



Es sieht interessant aus. Wird es im wirklichen Leben funktionieren? Die Zeit wird zeigen.


Wie bei Stilen können wir ShapeAppearance nur auf eine ShapeAppearance anwenden.


Was gibt es zu einem dunklen Thema?


Die Veröffentlichung von Android Q wird sehr bald stattfinden und damit wird das offizielle dunkle Thema zu uns kommen.


Eine der vielleicht interessantesten und spektakulärsten Funktionen der neuen Android-Version ist die automatische Anwendung eines dunklen Themas für die gesamte Anwendung mit einer Codezeile.


Hört sich toll an, lass es uns versuchen. Ich schlage vor, einen Lieblings- Gitlab-Kunden aus Terrakok zu nehmen .


Neulackieren der Anwendung zulassen (standardmäßig deaktiviert):


 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- ... --> <item name="android:forceDarkAllowed">true</item> </style> 

Das android:forceDarkAllowed ist mit API 29 (Android Q) verfügbar.


Wir fangen an, schauen Sie, was passiert ist:



Stimmen Sie zu, dass es für eine Codezeile sehr cool aussieht.


Natürlich gibt es Probleme - BottomNavigationBar verschmilzt mit dem Hintergrund, der Loader bleibt weiß, die Auswahl des Codes leidet und anscheinend hat mich alles, zumindest nichts Ernstes, beeindruckt.


Ich bin sicher, dass nicht so viel Zeit die Hauptprobleme lösen kann. Zum Beispiel das android:forceDarkAllowed des automatischen android:forceDarkAllowed für einzelne Ansichten (ja, es ist auch möglich - android:forceDarkAllowed ist für die Ansicht in einer Markup-Datei verfügbar).


Es ist zu beachten, dass dieser Modus nur für helle Themen verfügbar ist. Wenn Sie ein dunkles Thema verwenden, funktioniert ein erzwungenes dunkles Thema nicht.


Arbeitsempfehlungen finden Sie in der Dokumentation und auf material.io .


Und wenn wir alles alleine machen wollen?


Unabhängig davon, wie einfach es ist, ein erzwungenes dunkles Thema zu verwenden, ist dieser Modus ohne Flexibilität. Tatsächlich funktioniert alles nach vordefinierten Regeln, die möglicherweise nicht zu uns und vor allem zum Kunden passen. Ich denke, dass eine solche Entscheidung als vorübergehend angesehen werden kann, bis wir ein dunkles Thema umsetzen.


In API 8 (Froyo) wurde das Qualifikationsmerkmal -night hinzugefügt, mit dem bis heute ein dunkles Thema angewendet wird. Sie können das gewünschte Thema je nach Tageszeit automatisch anwenden.


In DayNight Themen wird eine solche Implementierung bereits verwendet, wir müssen sie nur erben.


Versuchen wir, unsere eigenen zu schreiben:


 ../values/themes.xml <style name="Theme.DayNight.Base" parent="Theme.MaterialComponents.Light"/> <style name="Theme.MyApp.Main" parent="Theme.DayNight.Base> <!-- ... --> </style> ../values-night/themes.xml <style name="Theme.DayNight.Base" parent="Theme.MaterialComponents"/> 

In der üblichen Ressource für das Thema ( values/themes.xml ) erben wir vom hellen Thema, in der "Nacht" ( values-night/themes.xml ) erben wir vom dunklen Thema.


Das ist alles. Wir haben eine Bibliotheksimplementierung eines dunklen Themas. Jetzt sollten wir Ressourcen für zwei Themen unterstützen.


Um zwischen Themen zu wechseln, während die Anwendung ausgeführt wird, können Sie AppCompatDelegate.setDefaultNightMode , das die folgenden Parameter verwendet:


  • MODE_NIGHT_NO - MODE_NIGHT_NO ;
  • MODE_NIGHT_YES - Dunkles Thema;
  • MODE_NIGHT_AUTO_BATTERY - Automatischer Modus. Das dunkle Thema wird aktiviert, wenn der Energiesparmodus aktiv ist.
  • MODE_NIGHT_FOLLOW_SYSTEM - Modus basierend auf den Systemeinstellungen.

Was sollten wir bei der Arbeit mit Themen und Stilen beachten?


Wie bereits erwähnt, hat Google offiziell damit begonnen, ein dunkles Thema zu erzwingen. Ich bin sicher, dass viele Kunden Fragen erhielten: „Können wir ein dunkles Thema hinzufügen?“. Es ist gut, wenn Sie von Anfang an alles richtig machen, und es fällt Ihnen leicht, die hellen Farben in dunkle zu ändern, während Sie eine komplett neu gestrichene Anwendung erhalten.


Dies ist leider nicht immer der Fall. Es gibt alte Anwendungen, die einen erheblichen Aufwand erfordern, um die erforderlichen Änderungen vorzunehmen.


Versuchen wir, Empfehlungen für die Zusammenarbeit mit Stilen zu formulieren:


1. Der Farbwähler


Ich denke, dass jeder Entwickler mit einer Situation konfrontiert ist, in der im neuen Layout eine seltsame Farbe erscheint, die noch nicht in der Anwendungspalette definiert ist. Was ist in diesem Fall zu tun?


Die richtige Antwort ist, mit dem Designer zu sprechen und zu versuchen, eine Farbpalette zu entwickeln. Jetzt gibt es viele Programme (Zeplin, Sketch usw.), mit denen Sie Primärfarben rendern und dann wiederverwenden können.


Je früher Sie dies tun, desto weniger Kopfschmerzen werden Sie in Zukunft haben.


2. Buchstabiere Farben mit ihren Eigennamen


In jeder Anwendung gibt es eine Farbe mit vielen Helligkeitsoptionen. Sie können damit beginnen, Namen für sie zu erfinden:


 <color name="green_tiny">...</color> <color name="green_light">...</color> <color name="green_dark">...</color> 

Stimmen Sie zu, es sieht nicht sehr gut aus. Es stellt sich sofort die Frage: Welche Farbe ist heller als tiny oder light ? Und wenn wir ein Dutzend Optionen haben?


colorVariant Sie sich am besten an das Google-Konzept und fügen Sie den Farbnamen die entsprechende Helligkeit hinzu (Google nennt diese Farboption - colorVariant ):


 <color name="material_green_300">...</color> <color name="material_green_700">...</color> <color name="material_green_900">...</color> 

Mit diesem Ansatz können wir eine beliebige Anzahl von Helligkeitsoptionen einer Farbe haben und müssen uns keine spezifischen Namen einfallen lassen, was sehr schwierig ist.


3. Von einer bestimmten Farbe abstrahieren, wenn sie sich in verschiedenen Themen ändert


Da wir eine Anwendung schreiben, in der es mindestens zwei Themen geben wird, können wir es uns nicht leisten, auf eine bestimmte Farbe zu verweisen, wenn sie in den Themen auf unterschiedliche Weise implementiert ist.


Schauen wir uns ein Beispiel an:



Wir sehen, dass in einem hellen Thema beispielsweise die Symbolleiste lila und im Dunkeln dunkelgrau gefärbt ist. Wie würden wir dieses Verhalten nur mit den Funktionen von Themen implementieren?


Alles ist ganz einfach - wir erstellen ein Attribut und implementieren es in hellen und dunklen Themen mit der entsprechenden Farbe, wie zuvor beschrieben.


Google empfiehlt, Attributnamen mit der Verwendungssemantik zu verknüpfen.


4. Haben Sie keine Angst, Ressourcendateien zu erstellen


Wenn in styles.xml viele verschiedene Stile, Themen und Attribute eingegeben werden, ist die styles.xml schwierig.


Es ist am besten, alles in separate Dateien zu gruppieren:


 themes.xml — Theme & ThemeOverlay styles.xml — Widget styles type.xml — TextAppearance, text size etc shape.xml — ShapeAppearance motion.xml — Animations styles system_ui.xml — Booleans, colors for UI control //may be other files 

Eine solch einfache Regel vermeidet Gottesakten und daher ist es einfacher, Stile beizubehalten.


5. Maximal wiederverwenden


Was tun wir, wenn wir ein Attribut neu definieren möchten, das nur in einer bestimmten Version der API verfügbar ist?


Wir können zwei separate Themen erstellen:


 ../values/themes.xml <style name="Theme.MyApp.Main" parent=”Theme.MaterialComponents.NoActionBar”> <!--Many definition--> </style> ../values-v27/themes.xml <style name="Theme.MyApp.Main" parent=”Theme.MaterialComponents.NoActionBar”> <!--Many definition--> <name="android:windowLightNavigationBar">...</item> </style> 

Haben wir jetzt ein Thema mit allen Parametern für jede Version der API? Nein, natürlich! Wir werden ein grundlegendes Thema erstellen, in dem die grundlegenden Attribute, die für alle Versionen der API verfügbar sind, bestimmt und in der gewünschten Version der API von dieser geerbt werden:


 ../values/themes.xml <style name="Theme.MyApp.Base" parent=”Theme.MaterialComponents.DayNight.NoActionBar”> <!--Many definition--> </style> <style name="Theme.MyApp.Main" parent=”Theme.MyApp.Base”/> ../values-v27/themes.xml <style name="Theme.MyApp.Base.V27" parent="Theme.MyApp.Base"> <name="android:windowLightNavigationBar">...</item> </style> <style name="Theme.MyApp.Main" parent=”Theme.MyApp.Base.V27”/> 

Nach diesem Prinzip werden alle Themen in der Standardbibliothek erstellt.


6. Verwenden Sie Vektorressourcen und Farbton


Ich denke, es lohnt sich nicht zu sagen, warum Vektorressourcen gut sind. Jeder weiß es bereits (nur für den Fall, ein Link zur Dokumentation ). Das Abtönen hilft uns, sie in Themenfarben zu färben.


In diesem Beispiel können Sie sehen, was Tönen ist und wie Sie damit arbeiten.


7.? Android: attr / ... vs? Attr / ...


Beim Zugriff auf Ressourcen haben wir die Möglichkeit, sowohl Systemattribute als auch Attribute aus der Materialkomponentenbibliothek zu verwenden. Es ist wichtig zu verstehen, dass einige Attribute nur mit einer bestimmten Version der API vorhanden sind. Wie wir alle wissen, führt der Zugriff auf eine nicht vorhandene Ressource zu einem Absturz (Flusen sagen uns natürlich, wenn etwas nicht stimmt, aber Sie sollten sich nicht immer darauf verlassen).


 android:background="?android:attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless" 

Im ersten Fall greifen wir auf die Systemressource zu, wie von android . Im zweiten Fall auf ein Attribut aus der Bibliothek, in dem die Abwärtskompatibilität implementiert ist.


Es ist besser, immer die zweite Option zu verwenden.


8. Geben Sie immer das übergeordnete Element für den Stil an


Es kann Parameter im übergeordneten Stil geben, ohne die die Komponente falsch gerendert wird. Geben Sie daher immer das übergeordnete Element an.


 <style name="Widget.MyApp.LoginInputLayout" parent="Widget.MaterialComponents.TextInputLayout.FilledBox"> <item name="errorTextColor">@color/colorError</item> </style> 

9. Thema, Stil oder ...?


Wenn Sie Ihre eigenen Themen und Stile erstellen, ist es hilfreich, wenn Sie ein Präfix angeben, das angibt, um welche Art von Stil es sich handelt und wofür es definiert ist. Eine solche Benennung macht es sehr einfach, Stile zu strukturieren und zu erweitern.


 <style name="Theme.MyApp.Main" parent=”...”/> <style name="Widget.MyApp.LoginInputLayout" parent="..."/> <style name="Widget.MyApp.LoginInputLayout.Brown"/> <style name="ThemeOverlay.MyApp.Login" parent=”...”/> 

10. Verwenden Sie TextAppearance


Es ist ein guter Ton, die Grundstile für den Text zu erweitern und überall zu verwenden.


Material Design: Typography , Typography Theming .


Fazit


, — , . - . Material Components. . Sketch — Material Theme Editor . . , .


Material Components GitHub — Modular and customizable Material Design UI components for Android . . , — sample, .


Nützliche Links:


Source: https://habr.com/ru/post/de461201/


All Articles