MDC-104 Android: Material Advanced Komponenty (Kotlin)

logo_components_color_2x_web_96dp.png

Komponenty Material (MDC) pomagają deweloperom wdrażać Material Design. MDC to stworzona przez zespół inżynierów i projektantów UX z Google biblioteka zawierająca dziesiątki atrakcyjnych i funkcjonalnych komponentów interfejsu. Jest dostępna na platformy Android, iOS, internet i Flutter.

material.io/develop

W codelabie MDC-103 dostosowaliśmy kolor, poziom i typografię komponentów Material Design (MDC), aby nadać aplikacji styl.

Komponent w systemie Material Design wykonuje zestaw wstępnie zdefiniowanych zadań i ma określone cechy, np. przycisk. Przycisk to jednak nie tylko sposób na wykonanie działania przez użytkownika, ale też wizualne wyrażenie kształtu, rozmiaru i koloru, które informuje użytkownika, że jest interaktywny i że po dotknięciu lub kliknięciu coś się stanie.

Wskazówki dotyczące Material Design opisują komponenty z perspektywy projektanta. Opisują one szeroki zakres podstawowych funkcji dostępnych na różnych platformach, a także elementy anatomiczne, z których składa się każdy komponent. Na przykład tło zawiera warstwę tylną i jej zawartość, warstwę przednią i jej zawartość, reguły ruchu i opcje wyświetlania. Każdy z tych komponentów można dostosować do potrzeb, przypadków użycia i treści poszczególnych aplikacji. Są to w większości tradycyjne widoki, elementy sterujące i funkcje z pakietu SDK platformy.

Wytyczne Material Design wymieniają wiele komponentów, ale nie wszystkie nadają się do ponownego wykorzystania w kodzie, dlatego nie znajdziesz ich w MDC. Możesz samodzielnie tworzyć takie funkcje, aby uzyskać niestandardowy styl aplikacji, korzystając z tradycyjnego kodu.

Co utworzysz

W tym ćwiczeniu dodasz tło do aplikacji Shrine. Będzie filtrować produkty wyświetlane w asymetrycznej siatce według kategorii. Użyjesz:

  • Kształt
  • Ruch
  • Tradycyjne klasy pakietu Android SDK

Komponenty MDC-Android w tym kursie

  • Kształt

Czego potrzebujesz

  • Podstawowa wiedza na temat programowania aplikacji na Androida
  • Android Studio (jeśli nie masz jeszcze tego środowiska, pobierz je tutaj)
  • emulator lub urządzenie z Androidem (dostępne w Android Studio);
  • Przykładowy kod (patrz następny krok)

Jak oceniasz swoje doświadczenie w tworzeniu aplikacji na Androida?

Początkujący Średnio zaawansowany Zaawansowany

Kontynuujesz naukę z MDC-103?

Jeśli udało Ci się ukończyć MDC-103, Twój kod powinien być gotowy do tego ćwiczenia. Przejdź do kroku 3.

Zaczynasz od zera?

Pobieranie aplikacji do ćwiczeń z programowania

Pobierz aplikację startową

Aplikacja startowa znajduje się w katalogu material-components-android-codelabs-104-starter/kotlin. Zanim zaczniesz, cd do tego katalogu.

...lub sklonuj go z GitHub

Aby sklonować ten codelab z GitHuba, uruchom te polecenia:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 104-starter

Wczytaj kod startowy w Android Studio

  1. Gdy kreator konfiguracji zakończy działanie i wyświetli się okno Witamy w Android Studio, kliknij Otwórz istniejący projekt Android Studio. Przejdź do katalogu, w którym został zainstalowany przykładowy kod, i wybierz kotlin –> shrine(lub wyszukaj na komputerze shrine), aby otworzyć projekt Shipping.
  2. Poczekaj chwilę, aż Android Studio utworzy i zsynchronizuje projekt. Wskaźniki aktywności w dolnej części okna Android Studio będą pokazywać postęp.
  3. W tym momencie Android Studio może zgłosić błędy kompilacji, ponieważ brakuje Ci pakietu SDK Androida lub narzędzi do kompilacji, np. takich jak te pokazane poniżej. Postępuj zgodnie z instrukcjami w Android Studio, aby zainstalować lub zaktualizować te komponenty i zsynchronizować projekt.

Dodawanie zależności projektu

Projekt musi być zależny od biblioteki pomocy MDC na Androida. Pobrany przykładowy kod powinien już zawierać tę zależność, ale warto wykonać poniższe czynności, aby się upewnić.

  1. Otwórz plik build.gradle modułu app i upewnij się, że blok dependencies zawiera zależność od MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (Opcjonalnie) W razie potrzeby edytuj plik build.gradle, aby dodać te zależności, i zsynchronizuj projekt.
dependencies {
    api 'com.google.android.material:material:1.1.0-alpha06'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}

Uruchom aplikację startową

  1. Sprawdź, czy konfiguracja kompilacji po lewej stronie przycisku Uruchom / Odtwórz to app.
  2. Naciśnij zielony przycisk Uruchom / Odtwórz, aby skompilować i uruchomić aplikację.
  3. Jeśli w oknie Wybierz miejsce wdrożenia na liście dostępnych urządzeń widzisz już urządzenie z Androidem, przejdź do kroku 8. W przeciwnym razie kliknij Utwórz nowe urządzenie wirtualne.
  4. Na ekranie Wybierz sprzęt wybierz telefon, np. Pixel 2, a potem kliknij Dalej.
  5. Na ekranie Obraz systemu wybierz najnowszą wersję Androida, najlepiej z najwyższym poziomem interfejsu API. Jeśli nie jest zainstalowana, kliknij wyświetlony link Pobierz i dokończ pobieranie.
  6. Kliknij Dalej.
  7. Na ekranie Android Virtual Device (AVD) pozostaw ustawienia bez zmian i kliknij Finish (Zakończ).
  8. W oknie docelowym wdrożenia wybierz urządzenie z Androidem.
  9. Kliknij OK.
  10. Android Studio skompiluje aplikację, wdroży ją i automatycznie otworzy na urządzeniu docelowym.

Gotowe! Na urządzeniu powinna być widoczna aplikacja Shrine.

Tło to powierzchnia znajdująca się najdalej z tyłu aplikacji, za wszystkimi innymi treściami i komponentami. Składa się z 2 warstw: tylnej (wyświetlającej działania i filtry) i przedniej (wyświetlającej treści). Możesz użyć tła, aby wyświetlać interaktywne informacje i działania, takie jak nawigacja czy filtry treści.

Ukrywanie treści siatki

W shr_product_grid_fragment.xml dodaj atrybut android:visibility="gone" do NestedScrollView, aby tymczasowo usunąć treść produktu:

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   android:visibility="gone"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

W tym regionie zainstalujemy tło. Aby uniknąć wyświetlania podziału między górnym paskiem aplikacji a treścią menu, która pojawia się na tle, ustawimy kolor tła taki sam jak kolor górnego paska aplikacji.

shr_product_grid_fragment.xml dodaj to jako pierwszy element w głównym elemencie FrameLayout przed elementem AppBarLayout:

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="100dp"
   android:paddingBottom="100dp">

</LinearLayout>

W sekcji styles.xml dodaj te informacje:

styles.xml

<style name="Widget.Shrine.Backdrop" parent="">
   <item name="android:background">?attr/colorAccent</item>
</style>

Brawo! Dodano piękne tło do interfejsu Shrine. Następnie dodamy menu.

Dodawanie menu

Menu to w zasadzie lista przycisków tekstowych. Dodamy go tutaj.

Utwórz nowy plik układu o nazwie shr_backdrop.xml w katalogu res -> layout i dodaj do niego ten kod:

shr_backdrop.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_featured_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_apartment_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_accessories_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_shoes_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_tops_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_bottoms_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_dresses_label" />

   <View
       android:layout_width="56dp"
       android:layout_height="1dp"
       android:layout_margin="16dp"
       android:background="?android:attr/textColorPrimary" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_account_label" />

</merge>

Dodaj tę listę do tagu LinearLayout, który został dodany w shr_product_grid_fragment.xml, za pomocą tagu <include>:

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="88dp">

   <include layout="@layout/shr_backdrop" />
</LinearLayout>

Skompiluj i uruchom. Ekran główny powinien wyglądać tak:

Tło zostało już skonfigurowane. Przywróćmy treści, które wcześniej ukryliśmy.

Zanim wprowadziliśmy zmiany w aplikacji Shrine w tym laboratorium, główna treść produktu znajdowała się na najbardziej oddalonej powierzchni. Dodanie tła sprawia, że treść jest bardziej wyeksponowana, ponieważ pojawia się na jego tle.

Dodawanie nowej warstwy

Powinniśmy ponownie wyświetlić warstwę siatki produktów. Usuń atrybut android:visibility="gone" z NestedScrollView:

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

Nadajmy styl warstwie przedniej z wycięciem w lewym górnym rogu. W Material Design ten typ dostosowywania jest określany jako kształt. Powierzchnie materiałów mogą być wyświetlane w różnych kształtach. Kształty dodają powierzchniom wyrazistości i stylu oraz mogą służyć do wyrażania marki. Kształty Material Design mogą mieć zaokrąglone lub ścięte rogi i krawędzie oraz dowolną liczbę boków. Mogą być symetryczne lub nieregularne.

Dodawanie kształtu

Zmień kształt siatki. Udostępniliśmy tło o niestandardowym kształcie, ale kształt wyświetla się prawidłowo tylko na Androidzie Marshmallow i nowszych wersjach. Możemy ustawić shr_product_grid_background_shape tło na NestedScrollView tylko w przypadku Androida Marshmallow i nowszych wersji. Najpierw dodaj id do NestedScrollView, abyśmy mogli odwoływać się do niego w kodzie, jak poniżej:

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:id="@+id/product_grid"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

Następnie ustaw tło programowo w ProductGridFragment.kt. Dodaj tę logikę, aby ustawić tło na końcu onCreateView(), tuż przed instrukcją return:

ProductGridFragment.kt

// Set cut corner background for API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       view.product_grid.background = context?.getDrawable(R.drawable.shr_product_grid_background_shape)
}

Na koniec zaktualizujemy productGridBackgroundColor zasób koloru (używany też przez tło niestandardowego kształtu) w ten sposób:

colors.xml

<color name="productGridBackgroundColor">#FFFBFA</color>

Kompilowanie i uruchamianie:

Nadaliśmy Shrine niestandardowy kształt na głównej powierzchni. Dzięki podniesieniu powierzchni użytkownicy mogą zobaczyć, że za przednią białą warstwą coś się znajduje. Dodajmy animację, aby użytkownicy mogli zobaczyć menu.

Ruch to sposób na ożywienie aplikacji. Ruch może być duży i dramatyczny, subtelny i minimalny lub mieć dowolny charakter pośredni. Rodzaj ruchu powinien być dostosowany do sytuacji. Ruch stosowany do powtarzających się regularnych działań powinien być niewielki i subtelny, aby nie zajmował zbyt dużo czasu. Inne sytuacje, np. pierwsze otwarcie aplikacji przez użytkownika, mogą być bardziej przyciągające uwagę i pomóc w zapoznaniu użytkownika z tym, jak korzystać z aplikacji.

Dodawanie animacji ujawniania do przycisku menu

Ruch polega na przesunięciu kształtu z przodu prosto w dół. Udostępniliśmy już detektor kliknięć, który wykona animację tłumaczenia arkusza w NavigationIconClickListener.kt. Możemy ustawić ten detektor kliknięć w ProductGridFragementonCreateView() w sekcji odpowiedzialnej za konfigurowanie paska narzędzi. Dodaj ten wiersz, aby ustawić odbiornik kliknięć na ikonie menu paska narzędzi:

ProductGridFragment.kt

view.app_bar.setNavigationOnClickListener(NavigationIconClickListener(activity!!, view.product_grid))

Sekcja powinna teraz wyglądać tak:

ProductGridFragment.kt

// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
view.app_bar.setNavigationOnClickListener(NavigationIconClickListener(activity!!, view.product_grid))

Skompiluj i uruchom. Naciśnij przycisk menu:

Ponowne naciśnięcie ikony menu nawigacyjnego powinno spowodować jego ukrycie.

Dostosowywanie ruchu przedniej warstwy

Ruch to świetny sposób na wyrażenie swojej marki. Zobaczmy, jak wygląda animacja ujawniania z użyciem innej krzywej czasowej.

Zaktualizuj odbiornik kliknięć w ProductGridFragment.kt, aby przekazać interpolator do odbiornika kliknięć ikony nawigacji w ten sposób:

ProductGridFragment.kt

view.app_bar.setNavigationOnClickListener(NavigationIconClickListener(activity!!, view.product_grid, AccelerateDecelerateInterpolator()))

Daje to inny efekt, prawda?

Ikony marki obejmują też znane ikony. Spersonalizujmy ikonę odkrywania i połączmy ją z tytułem, aby uzyskać niepowtarzalny wygląd zgodny z marką.

Zmiana ikony przycisku menu

Zmień przycisk menu, aby wyświetlać ikonę z motywem diamentu. Zaktualizuj pasek narzędzi w shr_product_grid_fragment.xml, aby używać nowej ikony marki, którą dla Ciebie przygotowaliśmy (shr_branded_menu), i ustaw atrybuty app:contentInsetStartandroid:padding, aby pasek narzędzi lepiej pasował do specyfikacji projektanta:

shr_product_grid_fragment.xml

<androidx.appcompat.widget.Toolbar
   android:id="@+id/app_bar"
   style="@style/Widget.Shrine.Toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:paddingStart="12dp"
   android:paddingLeft="12dp"
   android:paddingEnd="12dp"
   android:paddingRight="12dp"
   app:contentInsetStart="0dp"
   app:navigationIcon="@drawable/shr_branded_menu"
   app:title="@string/shr_app_name" />

Ponownie zaktualizujemy moduł nasłuchiwania kliknięć w onCreateView()ProductGridFragment.kt, aby przyjmował obiekty rysowalne paska narzędzi, gdy menu jest otwarte i gdy jest zamknięte, w ten sposób:

ProductGridFragment.kt

// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
view.app_bar.setNavigationOnClickListener(NavigationIconClickListener(
       activity!!,
       view.product_grid,
       AccelerateDecelerateInterpolator(),
       ContextCompat.getDrawable(context!!, R.drawable.shr_branded_menu), // Menu open icon
       ContextCompat.getDrawable(context!!, R.drawable.shr_close_menu))) // Menu close icon

Kompilowanie i uruchamianie:

Super! Gdy tło może zostać odsłonięte, wyświetla się ikona menu w kształcie rombu. Gdy menu można ukryć, zamiast niego wyświetla się ikona zamknięcia.

W trakcie tych 4 warsztatów z programowania zobaczysz, jak za pomocą komponentów Material tworzyć niepowtarzalne, eleganckie interfejsy użytkownika, które odzwierciedlają osobowość i styl marki.

Dalsze kroki

To ćwiczenie z programowania, MDC-104, zamyka tę serię. Więcej komponentów MDC-Android znajdziesz w katalogu komponentów MDC-Android.

Aby jeszcze bardziej utrudnić sobie to ćwiczenie, zmodyfikuj aplikację Shrine tak, aby zmieniała zdjęcia produktów wyświetlane po wybraniu kategorii z menu tła.

Aby dowiedzieć się, jak połączyć tę aplikację z Firebase w celu utworzenia działającego backendu, zapoznaj się z samouczkiem Firebase na Androida.

Udało mi się ukończyć to ćwiczenie w rozsądnym czasie i przy rozsądnym nakładzie pracy.

Zdecydowanie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Zdecydowanie się nie zgadzam

Chcę nadal korzystać z komponentów Material w przyszłości

Zdecydowanie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Zdecydowanie się nie zgadzam