1. Pengantar
Komponen Material (MDC) membantu developer menerapkan Desain Material. Dibuat oleh tim engineer dan desainer UX di Google, MDC memiliki banyak komponen UI yang indah dan fungsional serta tersedia untuk Android, iOS, web, dan Flutter.material.io/develop |
Apa yang dimaksud dengan Desain Material dan Komponen Material untuk Android?
Desain Material adalah sistem untuk mem-build produk digital yang menarik dan indah. Dengan menyatukan gaya, branding, interaksi, dan gerakan di bawah kumpulan prinsip dan komponen yang konsisten, tim produk dapat mewujudkan potensi desain terbesar mereka.
Untuk aplikasi Android, Komponen Material untuk Android (MDC Android) menggabungkan desain dan engineering dengan library komponen untuk menciptakan konsistensi di seluruh aplikasi Anda. Seiring berkembangnya sistem Desain Material, komponen ini diupdate untuk memastikan implementasi piksel-sempurna yang konsisten dan kepatuhan terhadap standar pengembangan front-end Google. MDC juga tersedia untuk web, iOS, dan Flutter.
Dalam codelab ini, Anda akan membangun halaman login menggunakan beberapa komponen Android MDC.
Yang akan Anda bangun
Codelab ini adalah codelab pertama dari 4 yang akan memandu Anda membangun aplikasi bernama Shrine, sebuah aplikasi Android e-commerce yang menjual pakaian dan perlengkapan rumah. Kursus ini akan menunjukkan cara menyesuaikan komponen agar mencerminkan merek atau gaya apa pun menggunakan MDC-Android.
Dalam codelab ini, Anda akan mem-build halaman login untuk Shrine yang berisi:
- Dua kolom teks, yang pertama untuk memasukkan nama pengguna dan yang kedua untuk sandi
- Dua tombol, satu untuk "Cancel" dan satu untuk "Berikutnya"
- Nama aplikasi (Shrine)
- Gambar logo Shrine
Komponen Android MDC dalam codelab ini
- Kolom Teks
- Tombol
Yang Anda butuhkan
- Pengetahuan dasar tentang pengembangan Android
- Android Studio (download di sini jika Anda belum memilikinya)
- Emulator atau perangkat Android (tersedia melalui Android Studio)
- Kode contoh (lihat langkah berikutnya)
Bagaimana Anda menilai tingkat pengalaman Anda dalam membangun aplikasi Android?
2. Menyiapkan lingkungan pengembangan
Memulai Android Studio
Saat Anda membuka Android Studio, jendela yang berjudul "Welcome to Android Studio" akan ditampilkan. Namun, jika ini adalah pertama kalinya Anda meluncurkan Android Studio, selesaikan langkah-langkah Wizard Penyiapan Android Studio dengan nilai default. Langkah ini dapat memerlukan waktu beberapa menit untuk mendownload dan menginstal file yang diperlukan, jadi jangan ragu untuk membiarkan proses ini berjalan di latar belakang sembari Anda melakukan bagian berikutnya.
Mendownload aplikasi codelab awal
Aplikasi awal terletak di direktori material-components-android-codelabs-101-starter/java
.
...atau meng-clone codelab dari GitHub
Untuk meng-clone codelab ini dari GitHub, jalankan perintah berikut:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 101-starter
Memuat kode awal di Android Studio
- Setelah wizard penyiapan selesai dan jendela Welcome to Android Studio ditampilkan, klik Open an existing Android Studio project. Buka direktori tempat Anda menginstal kode contoh, lalu pilih java -> kuil (atau telusuri shrine di komputer Anda) untuk membuka project Shrine.
- Tunggu Android Studio mem-build dan menyinkronkan project, seperti yang ditunjukkan oleh indikator aktivitas di bagian bawah jendela Android Studio.
- Pada tahap ini, Android Studio dapat memunculkan beberapa error build karena alat build atau Android SDK tidak ada, seperti yang ditampilkan di bawah. Ikuti petunjuk di Android Studio untuk menginstal/mengupdate versi ini dan menyinkronkan project Anda.
Menambahkan dependensi project
Project ini memerlukan dependensi pada MDC Android support library. Kode contoh yang Anda download seharusnya sudah mencantumkan dependensi ini, tetapi sebaiknya lakukan langkah-langkah berikut untuk memastikannya.
- Buka file
build.gradle
modulapp
dan pastikan blokdependencies
menyertakan dependensi pada Android MDC:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Opsional) Jika perlu, edit file
build.gradle
untuk menambahkan dependensi berikut dan sinkronkan project.
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' }
Menjalankan aplikasi awal
|
Berhasil! Kode awal untuk halaman login Shrine akan berjalan di emulator Anda. Anda akan melihat nama "Shrine" dan logo Shrine tepat di bawahnya.
Mari kita lihat kodenya. Kami telah menyediakan framework navigasi Fragment
sederhana dalam kode contoh untuk menampilkan fragmen dan menavigasi antar-fragmen.
Buka MainActivity.java
di direktori shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.java.shrine
. Akan berisi seperti ini:
MainActivity.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements NavigationHost {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shr_main_activity);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new LoginFragment())
.commit();
}
}
/**
* Navigate to the given fragment.
*
* @param fragment Fragment to navigate to.
* @param addToBackstack Whether or not the current fragment should be added to the backstack.
*/
@Override
public void navigateTo(Fragment fragment, boolean addToBackstack) {
FragmentTransaction transaction =
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment);
if (addToBackstack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
}
Aktivitas ini menampilkan file tata letak R.layout.shr_main_activity
, yang ditentukan dalam shr_main_activity.xml
.
Anda dapat melihat bahwa dalam onCreate(),
, MainActivity.java
memulai transaksi Fragment
untuk menampilkan LoginFragment
. LoginFragment.
Itulah yang akan kita modifikasi untuk codelab ini. Aktivitas ini juga mengimplementasikan metode navigateTo(Fragment)
, yang ditentukan dalam NavigationHost
, yang memungkinkan setiap fragmen menavigasi ke fragmen yang berbeda.
Command + Click (atau Control + Click) shr_main_activity
dalam file aktivitas untuk membuka file tata letak, atau buka file tata letak di 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" />
Di sini, kita melihat <FrameLayout>
sederhana yang berfungsi sebagai penampung untuk setiap fragmen yang ditampilkan aktivitas. Mari kita buka LoginFragment.java
.
LoginFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
/**
* Fragment representing the login screen for Shrine.
*/
public class LoginFragment extends Fragment {
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
// Snippet from "Navigate to the next Fragment" section goes here.
return view;
}
// "isPasswordValid" from "Navigate to the next Fragment" section method goes here
}
LoginFragment
meng-inflate file tata letak shr_login_fragment
dan menampilkannya di onCreateView()
. Mari kita lihat file tata letak shr_login_fragment.xml
untuk melihat tampilan halaman login.
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" />
<!-- Snippet from "Add text fields" section goes here. -->
<!-- Snippet from "Add buttons" section goes here. -->
</LinearLayout>
</ScrollView>
Di sini, kita dapat melihat <LinearLayout>
dengan <ImageView>
di bagian atas, yang mewakili "Shrine" logo.
Setelah itu, ada tag <TextView>
yang mewakili "SHRINE" label. Teks untuk label ini adalah resource string yang bernama @string/shr_app_name
. Jika Anda menekan Command + Click (atau Control + Click) nama resource string, atau membuka app -> res -> values -> strings.xml
, Anda dapat melihat file strings.xml
tempat resource string ditentukan. Jika resource string lainnya ditambahkan di masa mendatang, resource tersebut akan ditentukan di sini. Setiap resource dalam file ini harus memiliki awalan shr_
untuk menunjukkan bahwa resource tersebut merupakan bagian dari aplikasi Shrine.
Setelah Anda memahami kode awal, sekarang mari kita implementasikan komponen pertama kita.
3. Menambahkan kolom teks
Untuk memulai, kita akan menambahkan dua kolom teks ke halaman login kita agar orang-orang dapat memasukkan nama pengguna dan sandi mereka. Kita akan menggunakan komponen Kolom Teks MDC, yang menyertakan fungsi bawaan yang menampilkan label mengambang dan pesan error.
Menambahkan XML
Di shr_login_fragment.xml
, tambahkan dua elemen TextInputLayout
dengan turunan TextInputEditText
di dalam <LinearLayout>
, di bawah "SHRINE" label <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"
android:inputType="text"
android:maxLines="1" />
</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>
Cuplikan di atas mewakili dua kolom teks, masing-masing terdiri dari elemen <TextInputLayout>
dan turunan <TextInputEditText>
. Teks petunjuk untuk setiap kolom teks ditentukan dalam atribut android:hint
.
Kami telah menyertakan dua resource string baru untuk kolom teks – @string/shr_hint_username
dan @string/shr_hint_password
. Buka strings.xml
untuk melihat resource string ini.
strings.xml
...
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
...
Menambahkan validasi input
Komponen TextInputLayout
menyediakan fungsi masukan error bawaan.
Untuk menampilkan masukan error, lakukan perubahan berikut pada shr_login_fragment.xml
:
- Setel atribut
app:errorEnabled
ke benar (true) pada elemenTextInputLayout
Password . Tindakan ini akan menambahkan padding tambahan untuk pesan error di bawah kolom teks. - Tetapkan atribut
android:inputType
ke "textPassword
" di elemen PasswordTextInputEditText
. Tindakan ini akan menyembunyikan teks input di kolom sandi.
Dengan perubahan ini, kolom teks di shr_login_fragment.xml
akan terlihat seperti ini:
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"
android:inputType="text"
android:maxLines="1" />
</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>
Sekarang, coba jalankan aplikasi. Anda akan melihat halaman dengan dua kolom teks untuk "Nama pengguna" dan "Sandi"!
Lihat animasi label mengambang:
4. Menambahkan tombol
Selanjutnya, kita akan menambahkan dua tombol ke halaman login: "Cancel" dan "Next". Kita akan menggunakan komponen Tombol MDC, yang dilengkapi dengan efek riak tinta Desain Material bawaan.
Menambahkan XML
Di shr_login_fragment.xml
, tambahkan <RelativeLayout>
ke <LinearLayout>
, di bawah elemen TextInputLayout
. Kemudian, tambahkan dua elemen <MaterialButton>
ke <RelativeLayout>
.
File XML yang dihasilkan akan terlihat seperti ini:
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>
Selesai. Saat menjalankan aplikasi, riak tinta akan ditampilkan saat Anda mengetuk setiap tombol.
5. Membuka Fragment berikutnya
Terakhir, kita akan menambahkan beberapa kode Java ke LoginFragment.java
untuk menghubungkan "NEXT" kita ke fragmen lain. Anda akan melihat bahwa setiap komponen yang kita tambahkan ke tata letak memiliki id
yang ditetapkan ke tata letak tersebut. Kita akan menggunakan id
ini untuk mereferensikan komponen dalam kode kita dan menambahkan beberapa pemeriksaan error dan navigasi.
Mari kita tambahkan metode isPasswordValid
boolean pribadi di LoginFragment.java
di bawah onCreateView()
, dengan logika untuk menentukan apakah sandi valid atau tidak. Untuk tujuan demo ini, kita hanya perlu memastikan panjang {i>password<i} tersebut minimal terdiri dari 8 karakter:
LoginFragment.java
/*
In reality, this will have more complex logic including, but not limited to, actual
authentication of the username and password.
*/
private boolean isPasswordValid(@Nullable Editable text) {
return text != null && text.length() >= 8;
}
Berikutnya, tambahkan pemroses klik ke "Next" yang menetapkan dan menghapus error berdasarkan metode isPasswordValid()
yang baru saja kita buat. Di onCreateView()
, pemroses klik ini harus ditempatkan di antara baris inflater dan baris return view
.
Selanjutnya, mari kita tambahkan pemroses tombol ke sandi TextInputEditText
untuk memproses peristiwa utama yang akan menghapus error. Pemroses ini juga harus menggunakan isPasswordValid()
untuk memeriksa apakah sandi valid atau tidak. Anda dapat menambahkannya langsung di bawah pemroses klik di onCreateView()
.
Metode onCreateView() Anda sekarang akan terlihat seperti ini:
LoginFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
final TextInputLayout passwordTextInput = view.findViewById(R.id.password_text_input);
final TextInputEditText passwordEditText = view.findViewById(R.id.password_edit_text);
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
}
}
});
// Clear the error once more than 8 characters are typed.
passwordEditText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(null); //Clear the error
}
return false;
}
});
return view;
}
Sekarang, kita dapat menavigasi ke fragmen lain. Update OnClickListener
di onCreateView()
untuk membuka fragmen lain saat validasi error berhasil. Anda dapat melakukannya dengan menambahkan baris berikut untuk membuka ProductGridFragment
ke kasus else
dari pemroses klik:
LoginFragment.java
...
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
...
Pemroses klik Anda sekarang akan terlihat seperti berikut:
LoginFragment.java
...
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
}
}
});
...
Baris kode baru ini memanggil metode navigateTo()
dari MainActivity
untuk membuka fragmen baru – ProductGridFragment
. Saat ini, ini adalah halaman kosong yang akan Anda kerjakan di MDC-102.
Sekarang, bangun aplikasi. Lanjutkan dan tekan tombol Berikutnya.
Anda berhasil! Layar ini akan menjadi titik awal codelab berikutnya yang akan Anda kerjakan di MDC-102.
6. Selesai
Dengan menggunakan markup XML dasar dan ~30 baris Java, Komponen Material untuk library Android telah membantu Anda membuat halaman login menarik yang mematuhi pedoman Desain Material, dan terlihat serta berperilaku secara konsisten di semua perangkat.
Langkah berikutnya
Kolom Teks dan Tombol adalah dua komponen inti di library Android MDC, tetapi masih banyak lagi. Anda dapat mempelajari komponen lainnya di MDC Android. Atau, buka MDC 102: Tata Letak dan Struktur Desain Material untuk mempelajari panel aplikasi atas, tampilan kartu, dan tata letak petak. Terima kasih telah mencoba Komponen Material. Kami harap Anda menikmati codelab ini.