MDC-101 Android: podstawy komponentów (MDC) (Kotlin)

Logo_components_color_2x_web_96dp.png

Komponenty Material Design (MDC) pomagają deweloperom wdrażać Material Design. Firma MDC została stworzona przez zespół inżynierów i projektantów UX w Google. Zawiera ona dziesiątki pięknych i funkcjonalnych elementów interfejsu oraz jest dostępna w aplikacjach na Androida, iOS, internet oraz Flutter.

material.io/develop

Czym są Material Design i Komponenty Material Design na Androida?

Material Design to system do tworzenia atrakcyjnych i odważnych produktów cyfrowych. Dzięki połączeniu stylu, marki, interakcji i ruchu w ramach jednego zestawu zasad i komponentów zespoły produktowe mogą wykorzystać swój największy potencjał projektowy.

W przypadku aplikacji na Androida komponenty Material Design na Androida (MDC Android) łączą bibliotekę z komponentami, by zapewnić spójność w całej aplikacji. Wraz z rozwojem systemu Material Design te komponenty są aktualizowane, by zapewnić niezbędną implementację pikselową i spójność ze standardami deweloperskimi Google. Narzędzie MDC jest też dostępne w przeglądarkach internetowych, iOS i Flutter.

Dzięki nim dowiesz się, jak utworzyć stronę logowania, korzystając z kilku komponentów MDC na Androidzie.

Co stworzysz

To pierwsze z 4 ćwiczeń z programowania, które poprowadzą Cię przez proces tworzenia aplikacji o nazwie Shrine – aplikacji na Androida, która sprzedaje odzież i wyposażenie domu. Dowiesz się, jak dostosować komponenty, aby dopasować je do dowolnej marki lub stylu, korzystając z MDC na Androida.

W tym ćwiczeniu utworzysz stronę logowania do świątyni:

  • Dwa pola tekstowe do wpisania nazwy użytkownika i hasła
  • Dwa przyciski – jeden dla &"Anuluj&, a jeden dla &"Dalej"
  • Nazwa aplikacji (sanktuarium)
  • Logo Shrine&#39

Komponenty MDC na Androida w tym ćwiczeniu z programowania

  • Pole tekstowe
  • Przycisk

Czego potrzebujesz

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

Jak oceniasz tworzenie aplikacji na Androida?

Początkujący Średnio zaawansowany Zaawansowany

Uruchamianie Androida Studio

Gdy otworzysz Android Studio, powinno pojawić się okno zatytułowane „Witamy w Android Studio”. Jeśli jednak po raz pierwszy uruchamiasz Android Studio, wykonaj kreator konfiguracji Android Studio zawierający wartości domyślne. Pobieranie i instalowanie niezbędnych plików może potrwać kilka minut, więc w następnej sekcji pozostaw te ustawienia uruchomione w tle.

Pobierz aplikację początkujących z programowania

Pobierz aplikację startową

Aplikacja startowa znajduje się w katalogu material-components-android-codelabs-101-starter/kotlin.

...lub skopiuj z GitHuba

Aby skopiować to ćwiczenia z programowania na GitHubie, uruchom następujące polecenia:

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

Wczytywanie kodu startowego w Android Studio

  1. Gdy kreator konfiguracji zakończy się i pojawi 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 -> kaplica (lub wyszukaj na komputerze świątynię), aby otworzyć projekt dostawy.
  2. Zaczekaj, aż Android Studio skompiluje i zsynchronizuje projekt, na co wskazują wskaźniki aktywności na dole okna Android Studio.
  3. W tym momencie Android Studio może wyświetlić błędy kompilacji, ponieważ brakuje w nim pakietu Android SDK lub narzędzi do kompilacji (takich jak ten poniżej). Postępuj zgodnie z instrukcjami w Android Studio, aby zainstalować lub zaktualizować te projekty, a następnie zsynchronizować projekt.

Dodawanie zależności od projektu

Projekt potrzebuje zależności od biblioteki pomocy MDC na Androida. Pobrany przykładowy kod powinien już być widoczny na liście, ale zalecamy wykonanie tych czynności, aby się upewnić.

  1. Przejdź do pliku build.gradle modułu app i upewnij się, że blok dependencies zawiera zależność w MDC na Androida:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (Opcjonalnie) W razie potrzeby zmodyfikuj plik build.gradle, dodając 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'
}

Uruchamianie aplikacji startowej

  1. Sprawdź, czy konfiguracja kompilacji po lewej stronie przycisku Uruchom/Odtwórz ma wartość app.
  2. Naciśnij zielony przycisk Uruchom/Odtwórz, aby utworzyć i uruchomić aplikację.
  3. Jeśli w oknie Select Deployment Target (Wybierz cel wdrożenia) masz już dostępne 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, na przykład Pixel 2, i kliknij Dalej.
  5. Na ekranie Obraz systemu wybierz najnowszą wersję Androida, najlepiej na najwyższym poziomie interfejsu API. Jeśli nie jest zainstalowany, kliknij widoczny link Pobierz, aby go pobrać.
  6. Kliknij Dalej.
  7. Na ekranie Wirtualne urządzenie z Androidem (AVD) pozostaw ustawienia bez zmian i kliknij Zakończ.
  8. W oknie celu 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. Kod startowy strony logowania Shrine&#39 powinien być uruchomiony w emulatorze. Pod spodem powinna się pojawić nazwa „sanktuarium”.

Przyjrzyjmy się kodowi. W przykładowym kodzie opracowaliśmy prostą strukturę nawigacyjną Fragment, która umożliwia wyświetlanie fragmentów i poruszanie się między nimi.

Otwórz folder MainActivity.kt w katalogu shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine. Powinny zawierać te informacje:

MainActivity.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment

class MainActivity : AppCompatActivity(), NavigationHost {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.shr_main_activity)

       if (savedInstanceState == null) {
           supportFragmentManager
                   .beginTransaction()
                   .add(R.id.container, LoginFragment())
                   .commit()
       }
   }

   override fun navigateTo(fragment: Fragment, addToBackstack: Boolean) {
       val transaction = supportFragmentManager
               .beginTransaction()
               .replace(R.id.container, fragment)

       if (addToBackstack) {
           transaction.addToBackStack(null)
       }

       transaction.commit()
   }
}

Ta aktywność wyświetla plik układu R.layout.shr_main_activity zdefiniowany w shr_main_activity.xml.

Jak widać, w onCreate(), MainActivity.kt rozpoczyna transakcję Fragment, by wyświetlać LoginFragment. Na potrzeby tego ćwiczenia zmodyfikujemy LoginFragment. Aktywność obejmuje też metodę navigateTo(Fragment) zdefiniowaną w narzędziu NavigationHost, dzięki której każdy fragment może przejść do innego fragmentu.

Command + kliknięcie (lub Control + kliknij) shr_main_activity w pliku aktywności, by otworzyć plik układu, lub przejdź do pliku szablonu w app -> res -> layout -> shr_main_activity.xml.

shr_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity"/>

Widzimy tu prosty element <FrameLayout>, który działa jako kontener na wszystkie fragmenty, które wyświetla aktywność.

Teraz otwórzmy stronę LoginFragment.kt.

LoginFragment.kt

package com.google.codelabs.mdc.kotlin.shrine

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class LoginFragment : Fragment() {

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       return view
   }
}

LoginFragment zapełnia plik układu shr_login_fragment i wyświetla go w polu onCreateView().

Teraz przyjrzyjmy się plikowi układu shr_login_fragment.xml, aby zobaczyć, jak wygląda strona logowania.

shr_login_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="match_parent"
   android:background="@color/loginPageBackgroundColor"
   tools:context=".LoginFragment">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:clipChildren="false"
       android:clipToPadding="false"
       android:orientation="vertical"
       android:padding="24dp"
       android:paddingTop="16dp">

       <ImageView
           android:layout_width="64dp"
           android:layout_height="64dp"
           android:layout_gravity="center_horizontal"
           android:layout_marginTop="48dp"
           android:layout_marginBottom="16dp"
           app:srcCompat="@drawable/shr_logo" />

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:layout_marginBottom="132dp"
           android:text="@string/shr_app_name"
           android:textAllCaps="true"
           android:textSize="16sp" />
   </LinearLayout>
</ScrollView>

Widać na niej ikonę <LinearLayout> z logo <ImageView> na górze, symbolizujące logo świątyni.

Później znajduje się tag <TextView>, który reprezentuje etykietę świątyni. Tekst tej etykiety jest zasobem tekstowym o nazwie @string/shr_app_name. Jeśli klikniesz Command + Click (lub Control + Click) lub nazwę zasobu ciągu znaków, albo otworzysz app -> res -> values -> strings.xml, zobaczysz plik strings.xml, w którym zdefiniowane są zasoby ciągu znaków. Jeśli w przyszłości dodamy więcej zasobów, zostaną one zdefiniowane tutaj. Każdy zasób w tym pliku powinien mieć prefiks shr_ wskazujący, że są częścią aplikacji Shrine.

Skoro znasz już kod startowy, zaimplementuj nasz pierwszy komponent.

Na początek dodamy 2 pola tekstowe do strony logowania, by umożliwić wpisanie nazwy użytkownika i hasła. Wykorzystamy komponent Pole tekstowe MDC, które zawiera wbudowaną funkcję wyświetlania etykiety pływającej i komunikatów o błędach.

Dodawanie pliku XML

W elemencie shr_login_fragment.xml dodaj 2 elementy TextInputLayout z elementem podrzędnym TextInputEditText wewnątrz elementu <LinearLayout>, pod etykietą „SHRINE&quot” (<TextView>):

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

Powyższy fragment kodu reprezentuje 2 pola tekstowe, z których każde zawiera element <TextInputLayout> i element podrzędny <TextInputEditText>. Tekst podpowiedzi dla każdego pola tekstowego jest określony w atrybucie android:hint.

Do pola tekstowego dodaliśmy 2 nowe zasoby: @string/shr_hint_username i @string/shr_hint_password. Otwórz strings.xml, aby zobaczyć te zasoby ciągu znaków.

strings.xml,

<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>

Dodawanie walidacji danych wejściowych

Komponenty TextInputLayout mają wbudowane funkcje przekazywania informacji o błędach.

Aby zobaczyć komentarz o błędzie, wprowadź te zmiany w polu shr_login_fragment.xml:

  • Ustaw atrybut app:errorEnabled na true w elemencie Hasło TextInputLayout. W ten sposób dodasz dodatkowe pole do komunikatu o błędzie.
  • W elemencie android:inputType ustaw wartość textPassword" w elemencie Password (Hasło) TextInputEditText. Spowoduje to ukrycie tekstu w polu hasła.

Po tych zmianach pola tekstowe w pliku shr_login_fragment.xml powinny wyglądać tak:

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password"
   app:errorEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>

Teraz uruchom aplikację. Powinna wyświetlić się strona z 2 polami tekstowymi: "Nazwa użytkownika" i "Hasło"!

Zobacz animację na pływającej etykiecie:

Następnie dodamy 2 przyciski do strony logowania: "Anuluj&"Dalej." Użyjemy komponentu MDC Button, który zawiera wbudowany efekt fali atramentu w stylu Material Design.

Dodawanie pliku XML

W polu shr_login_fragment.xml dodaj <RelativeLayout> do <LinearLayout>, pod elementami TextInputLayout. Następnie dodaj do elementu <RelativeLayout> dwa elementy <MaterialButton>.

Powstały plik XML powinien wyglądać tak:

shr_login_fragment.xml

<RelativeLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <com.google.android.material.button.MaterialButton
       android:id="@+id/next_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentEnd="true"
       android:layout_alignParentRight="true"
       android:text="@string/shr_button_next" />

   <com.google.android.material.button.MaterialButton
       android:id="@+id/cancel_button"
       style="@style/Widget.MaterialComponents.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="12dp"
       android:layout_marginRight="12dp"
       android:layout_toStartOf="@id/next_button"
       android:layout_toLeftOf="@id/next_button"
       android:text="@string/shr_button_cancel" />

</RelativeLayout>

To już wszystko Gdy uruchomisz aplikację, po kliknięciu każdego przycisku pojawi się echa.

Na koniec dodamy fragment kodu Kotlin do adresu LoginFragment.kt, by połączyć przycisk „NEXT&quot” i przejść do innego fragmentu.

Dodajmy prywatną metodę logiczną isPasswordValid logiczną isPasswordValid w kolumnie LoginFragment.kt (poniżej) z logiką określającą, czy hasło jest poprawne. Na potrzeby tej demonstracji upewnij się, że hasło ma co najmniej 8 znaków:

LoginFragment.kt

private fun isPasswordValid(text: Editable?): Boolean {
   return text != null && text.length >= 8
}

Następnie dodaj detektor kliknięć do przycisku „Dalej”, by ustawić błąd i usunąć go na podstawie nowo utworzonej metody isPasswordValid(). W języku onCreateView() ten detektor kliknięć powinien być umieszczony między wierszem wiersza a wierszem return view.

Teraz dodajmy odbiornik klucza do hasła TextInputEditText, aby nasłuchiwał kluczowych zdarzeń, które usuwają błąd. Ten detektor powinien też użyć metody isPasswordValid(), by sprawdzić, czy hasło jest prawidłowe. Możesz go dodać bezpośrednio pod detektorem kliknięć w onCreateView().

Metoda onCreateView() powinna wyglądać mniej więcej tak:

LoginFragment.kt

override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment.
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       // Set an error if the password is less than 8 characters.
       view.next_button.setOnClickListener({
           if (!isPasswordValid(password_edit_text.text!!)) {
               password_text_input.error = getString(R.string.shr_error_password)
           } else {
               // Clear the error.
               password_text_input.error = null
           }
       })

       // Clear the error once more than 8 characters are typed.
       view.password_edit_text.setOnKeyListener({ _, _, _ ->
           if (isPasswordValid(password_edit_text.text!!)) {
               // Clear the error.
               password_text_input.error = null
           }
           false
       })

       return view
   }
}

Teraz możemy przejść do innego fragmentu. W onCreateView() zaktualizuj OnClickListener, aby przejść do innego fragmentu, gdy weryfikacja się uda. Kod clickListener powinien teraz wyglądać tak:

LoginFragment.kt

// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
   if (!isPasswordValid(password_edit_text.text!!)) {
       password_text_input.error = getString(R.string.shr_error_password)
   } else {
       // Clear the error.
       password_text_input.error = null
       // Navigate to the next Fragment.
       (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
   }
})

Do wiersza else detektora kliknięć dodaliśmy wiersz (activity as NavigationHost).navigateTo(ProductGridFragment(), false). Ten wiersz wywołuje metodę navigateTo() z elementu MainActivity, aby przejść do nowego fragmentu – ProductGridFragment. Obecnie jest to pusta strona, nad którą będziesz pracować w MDC-102.

Teraz skompiluj aplikację. Naciśnij przycisk Dalej.

Udało Ci się wykorzystać wszystkie nagrody. Będzie to punkt wyjścia do kolejnego ćwiczenia z programowania, nad którym będziesz pracować w MDC-102.

Za pomocą podstawowych znaczników XML i około 30 wierszy Kotlina narzędzie Material Components z Androidem pomogło Ci stworzyć piękną stronę logowania zgodną z wytycznymi Material Design, a także wyglądało i działało konsekwentnie na wszystkich urządzeniach.

Dalsze kroki

Pole tekstowe i przycisk to dwa główne elementy biblioteki MDC na Androida, ale jest ich znacznie więcej. Możesz też zapoznać się z pozostałymi komponentami Androida MDC. Możesz też przejść do artykułu MDC 102: Material Design Structured and Layout, aby dowiedzieć się więcej o górnym pasku aplikacji, widoku karty i układzie siatki. Dziękujemy za wypróbowanie komponentów komponentów. Mamy nadzieję, że podobały Ci się ćwiczenia z programowania.

Ukończenie ćwiczeń z programowania było sporą ilością czasu i wysiłku.

Całkowicie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Całkowicie się nie zgadzam

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

Całkowicie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Całkowicie się nie zgadzam