Schreiben einer Android App für Filmfans - Teil 2 (Design)



Hallo Habr!

In diesem Artikel werden wir den Prozess des Erstellens von Bildschirmen basierend auf den Layouts aus dem ersten Teil betrachten .

Bildschirmlayout


Startbildschirm


Der Hauptbildschirm enthält Fragmente und Navigationsmenüs. Lassen Sie uns das Menü schreiben, nachdem Sie die Symbole erstellt haben. Öffnen Sie dazu den Zeichenordner , klicken Sie auf Neu und wählen Sie Vektor-Assets . Klicken Sie im angezeigten Fenster auf ClipArt und wählen Sie die Symbole Einstellungen , Suchen und Einfügen von Inhalten . Die Größe wird 24 mal 24 verlassen.

Erstellen Sie eine Zeichenfolgendatei im Werteordner und fügen Sie die folgenden Zeilen hinzu:

<resources> <string name="title_home">Home</string> <string name="title_search">Search</string> <string name="title_settings">Settings</string> </resources> 

Das Einfügen aller Zeilen in eine Datei vereinfacht die weitere Lokalisierung der Anwendung.
Wenn Sie eine andere Sprache hinzufügen möchten, z. B. Russisch, erstellen Sie eine Datei mit dem Attribut " Gebietsschema" , wählen Sie die gewünschte Sprache aus der Liste "Sprache" aus und fügen Sie nach der Übersetzung dieselben Zeilen hinzu.

Nun fahren wir direkt mit der Erstellung des Menüs fort. Erstellen Sie im Menüordner die Menü-Resourse-Datei , nennen Sie sie " bottom_nav_menu " und fügen Sie den folgenden Code hinzu:

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/navigation_home" android:icon="@drawable/ic_content_paste_black_24dp" android:title="@string/title_home"/> <item android:id="@+id/navigation_search" android:icon="@drawable/ic_search_black_24dp" android:title="@string/title_search"/> <item android:id="@+id/navigation_settings" android:icon="@drawable/ic_settings_black_24dp" android:title="@string/title_settings"/> </menu> 

Erstellen Sie eine Stildatei im Werteordner und fügen Sie den folgenden Code hinzu:

 <resources> <style name="MyLinearLayout"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:orientation">vertical</item> </style> </resources> 

Erstellte Stile werden für Ansichten verwendet, um Markup- und Stildateien zu trennen. Sie enthalten Formatierungsattribute, die für das Erscheinungsbild und Verhalten von Elementen verantwortlich sind. Zuerst können Sie alle Attribute in die Markup-Datei schreiben und sie dann in die Stildatei exportieren, indem Sie auf die folgende Kombination klicken: RMB -> Refactor -> Extract -> Style . Der Stil ist nur in Innenansichten verfügbar. Lesen Sie hier mehr darüber.

Danach können Sie direkt mit dem Erstellen eines Layouts für die Aktivität fortfahren. Erstellen Sie im Layoutordner eine Layout-Ressourcendatei , nennen Sie sie " activity_main " und fügen Sie den folgenden Code hinzu:

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity" style="@style/MyLinearLayout"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/fragment_container" android:layout_marginBottom="?attr/actionBarSize" /> <android.support.design.widget.BottomNavigationView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/nav_view" app:menu="@menu/bottom_nav_menu" android:background="#6986c2" android:layout_gravity="bottom"/> </FrameLayout> 

Mal sehen, was passiert ist.



Startbildschirm


Öffnen Sie die Stildatei und fügen Sie Stile für die Symbolleiste mit einer untergeordneten TextView und RecyclerView hinzu:

  <style name="MyToolbar"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:background">#6986c2</item> </style> <style name="Toolbar_TextView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:gravity">center</item> </style> <style name="MyRecyclerView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:background">#fff</item> </style> 

Fügen Sie der Zeichenfolgendatei die folgenden Zeilen hinzu:

  <string name="desc_home">Notification list</string> <string name="movie_title">Movie title</string> <string name="default_imdb_rating">IMDb rating: 7,4</string> 

Erstellen Sie nun ein Layout mit dem Namen " fragment_home " und fügen Sie den folgenden Code hinzu:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/MyLinearLayout"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_home" style="@style/MyToolbar"> <TextView android:text="@string/desc_home" style="@style/Toolbar_TextView"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.RecyclerView android:id="@+id/recView_home" style="@style/MyRecyclerView"/> </LinearLayout> 

Fügen Sie dem Zeichenordner die Symbole Benachrichtigung und Keine Benachrichtigung hinzu.

Fahren wir mit dem Erstellen eines Listenelements fort. Fügen Sie die Datei " item_movie " zum Layoutordner hinzu und schreiben Sie den folgenden Code hinein:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="120dp" app:cardCornerRadius="16dp" android:layout_marginLeft="16dp" android:layout_marginTop="8dp" android:layout_marginRight="16dp" android:layout_marginBottom="8dp" app:cardBackgroundColor="#00FFFFFF"> <ImageView android:layout_width="98dp" android:layout_height="98dp" app:srcCompat="@mipmap/ic_launcher" android:id="@+id/item_image" android:layout_gravity="center|start" android:layout_marginLeft="10dp"/> <TextView android:text="@string/movie_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/item_title" android:layout_marginTop="18dp" android:layout_marginLeft="120dp" android:textStyle="bold" android:textColor="@android:color/black" android:ellipsize="end" android:maxLines="1" android:layout_marginRight="16dp"/> <TextView android:text="@string/default_imdb_rating" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/item_rating" android:layout_marginLeft="120dp" android:layout_marginTop="50dp"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_notifications_black_24dp" android:id="@+id/item_notification" android:layout_gravity="bottom|right" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" tools:ignore="VectorDrawableCompat"/> </android.support.v7.widget.CardView> 

Schauen wir uns das Ergebnis an:



Registerkarte "Suche"


Fügen Sie in der Zeichenfolgendatei die Kopfzeile für die Symbolleiste hinzu:

 <string name="desc_settings">Preferences</string> 

Erstellen Sie ein Layout mit dem Namen " fragment_search " und fügen Sie gleichzeitig den folgenden Codeblock hinzu:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/MyLinearLayout"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_search" style="@style/MyToolbar"> <android.support.v7.widget.SearchView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/border_search_view" android:layout_marginRight="15dp" android:id="@+id/search_view"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.RecyclerView android:id="@+id/recView_search" style="@style/MyRecyclerView"/> </LinearLayout> 

Mal sehen, das Ergebnis:



Bildschirm für die Registerkarte Einstellungen


Dieser Bildschirm erwies sich als der umfangreichste, da er nur wenige sich wiederholende Stile aufweist.

Fügen Sie der Stildatei den Code für TextView und CardView hinzu:

  <style name="MyTextView"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/black</item> <item name="android:layout_marginLeft">16dp</item> <item name="android:layout_marginTop">8dp</item> <item name="android:layout_marginBottom">8dp</item> <item name="android:typeface">normal</item> </style> <style name="MyCardView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_margin">16dp</item> </style> 

Fügen Sie der Zeichenfolgendatei außerdem einige weitere Zeilen hinzu:

 <string name="imdb_rating">IMDb rating</string> <string name="default_rating">6</string> <string name="movie_genres">Movie genres</string> 

Sie müssen auch das Sternrahmensymbol zum Zeichenordner hinzufügen .

Erstellen Sie ein Layout mit dem Namen " fragment_settings " und fügen Sie den folgenden Code hinzu:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" style="@style/MyLinearLayout" android:background="#fff"> <android.support.v7.widget.Toolbar style="@style/MyToolbar" android:id="@+id/toolbar_home" app:title="@string/desc_home"> <TextView android:text="@string/desc_settings" style="@style/Toolbar_TextView"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.CardView app:cardCornerRadius="16dp" app:cardBackgroundColor="#00FFFFFF" style="@style/MyCardView"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_star_border_black_24dp" android:layout_gravity="right" android:layout_marginRight="50dp" android:layout_marginTop="8dp" tools:ignore="VectorDrawableCompat"/> <TextView android:text="@string/default_rating" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rating_value" android:layout_gravity="right" android:layout_marginRight="40dp" android:layout_marginTop="8dp" android:textColor="#666666"/> <TextView android:text="@string/imdb_rating" android:id="@+id/textView" style="@style/MyTextView"/> <SeekBar style="@style/Widget.AppCompat.SeekBar.Discrete" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="6" android:id="@+id/seek_bar" android:layout_marginLeft="16dp" android:layout_marginTop="50dp" android:layout_marginBottom="20dp" android:layout_marginRight="16dp"/> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView app:cardCornerRadius="16dp" app:cardBackgroundColor="#00FFFFFF" style="@style/MyCardView"> <TextView android:text="@string/movie_genres" style="@style/MyTextView"/> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00FFFFFF" android:layout_marginLeft="16dp" android:layout_marginTop="36dp" android:layout_marginBottom="16dp" android:layout_marginRight="16dp" android:id="@+id/recView_settings"/> </android.support.v7.widget.CardView> </LinearLayout> 

Erstellen Sie ein Element für die Liste. Fügen Sie die Datei " item_genre " zum Layoutordner hinzu und schreiben Sie den folgenden Code:

 <?xml version="1.0" encoding="utf-8"?> <CheckBox xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:text="@string/movie_genres" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/item_check_box" /> 

Schauen wir uns das Ergebnis an:



Designtests


Mal sehen, wie oft derselbe Abschnitt des Bildschirms neu gezeichnet wird, dh, es wird zusätzliche Arbeit geleistet.

In OrdnungSchlecht



Farbe blau - zeichnet einmal neu. Gut.
Farbe grün - zeichnet zweimal neu. Optimierung erforderlich.
Farbe hellrot - wird dreimal neu gezeichnet. Sehr schlecht.
Rote Farbe - Zeichnet mehr als viermal neu. Etwas ist schief gelaufen.
Und wenn nichts übermalt wird, wird das Grundstück nicht neu gezeichnet. Ausgezeichnete Arbeit.

Warum ist auf dem zweiten Screenshot alles rot? Jedem Layout, RecyclerView und CardView wurde ein weißer Hintergrund hinzugefügt, wodurch sich Ebenen überlappten. Dies ist bei dem oben beschriebenen Design nicht der Fall, das Beispiel zeigt nur die erfolglose Anwendung der Stilisierung.

Im ersten Screenshot wurde in LinearLayout nur ein Hintergrund für das Home-Fragment verwendet, dessen Neuzeichnung programmgesteuert mit der folgenden Methode abgebrochen wurde:

 window.setBackgroundDrawable(null) 


Mal sehen, wie lange es dauert, Frames zu rendern.

Für den ersten FallFür den zweiten Fall



Cyan ist für die Zeit verantwortlich, die zum Erstellen und Aktualisieren der Ansicht benötigt wird.
Der violette Teil gibt die Zeit an, die zum Übertragen der Rendering-Ressourcen des Streams benötigt wird.
Rot ist die Zeit zum Zeichnen.
Eine orange Farbe zeigt an, wie lange der Prozessor gewartet hat, bis die GPU ihre Arbeit abgeschlossen hat. Es ist eine Quelle von Problemen mit großen Mengen. - Alexander Klimov


In unserem Fall werden fast alle Registerkarten in weniger als 16 ms gezeichnet, dh unterhalb des grünen Balkens. Wenn der Balken größer als diese Zeile ist, wird das Programm möglicherweise langsamer.

Fazit


Im nächsten Artikel werden wir uns mit der Arbeit mit dem Server befassen. Während der Autor ihn schreibt, können Sie das aktuelle Design in der folgenden Umfrage bewerten.

Wenn irgendwelche Punkte unklar bleiben, stellen Sie Fragen in den Kommentaren.

Wenn Sie der Meinung sind, dass Design (XML) vereinfacht oder verbessert werden kann, schreiben Sie bitte darüber.

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


All Articles