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'
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?
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
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
- 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.
- Zaczekaj, aż Android Studio skompiluje i zsynchronizuje projekt, na co wskazują wskaźniki aktywności na dole okna Android Studio.
- 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ć.
- Przejdź do pliku
build.gradle
modułuapp
i upewnij się, że blokdependencies
zawiera zależność w MDC na Androida:
api 'com.google.android.material:material:1.1.0-alpha06'
- (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
|
Gotowe. Kod startowy strony logowania Shrine' 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"” (<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
natrue
w elemencie HasłoTextInputLayout
. 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"” 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.