Material Components (MDC) ช่วยให้นักพัฒนาซอฟต์แวร์นํา Material Design ไปใช้ได้ MDC สร้างโดยทีมวิศวกรและนักออกแบบ UX ที่ Google มีคอมโพเนนต์ UI ที่สวยงามและใช้งานได้จํานวนมาก และพร้อมใช้งานสําหรับ Android, iOS, เว็บ และ Flitter material.io/develop |
Material Design และคอมโพเนนต์วัสดุสําหรับ Android คืออะไร
Material Design เป็นระบบสําหรับการสร้างผลิตภัณฑ์ดิจิทัลที่โดดเด่นและสวยงาม ทีมผลิตภัณฑ์จะตระหนักถึงศักยภาพในการออกแบบที่ยิ่งใหญ่ที่สุดเมื่อรวมรูปแบบ การสร้างแบรนด์ การโต้ตอบ และการเคลื่อนไหวเข้าด้วยกันภายใต้หลักการและองค์ประกอบที่สอดคล้องกัน
สําหรับแอปพลิเคชัน Android คอมโพเนนต์วัสดุสําหรับ Android (MDC Android) รวมการออกแบบและวิศวกรรมเข้ากับไลบรารีของคอมโพเนนต์สําหรับการสร้างความสอดคล้องในแอป เนื่องจากระบบ Material Design มีการเปลี่ยนแปลงอยู่เสมอ คอมโพเนนต์เหล่านี้จึงได้รับการอัปเดตเพื่อให้การใช้งานที่สอดคล้องและสมบูรณ์แบบของพิกเซลสอดคล้องกับมาตรฐานการพัฒนาส่วนหน้าของ Google MDC ยังใช้ได้กับเว็บ, iOS และ Flitter
ใน Codelab นี้ คุณจะต้องสร้างหน้าเข้าสู่ระบบโดยใช้คอมโพเนนต์ Android M##39 หลายรายการ
สิ่งที่คุณจะสร้าง
Codelab นี้เป็นรายการแรกของ 4 Codelab ที่จะแนะนําคุณในการสร้างแอปชื่อ Shrine ซึ่งเป็นแอป Android สําหรับอีคอมเมิร์ซที่ขายเสื้อผ้าและของใช้ในบ้าน โดยจะแสดงวิธีการปรับแต่งคอมโพเนนต์ให้แสดงถึงแบรนด์หรือสไตล์ใดๆ โดยใช้ MDC Android
ใน Codelab นี้ คุณจะต้องสร้างหน้าเข้าสู่ระบบสําหรับศาลเจ้าที่มีสิ่งต่อไปนี้
- ช่องข้อความ 2 ช่อง ช่องหนึ่งสําหรับป้อนชื่อผู้ใช้ และอีกช่องสําหรับรหัสผ่าน
- ปุ่ม 2 ปุ่ม อีกปุ่มหนึ่งสําหรับ "Cancel" และอีกปุ่มหนึ่งสําหรับ "Next"
- ชื่อแอป (ศาลเจ้า)
- รูปภาพของโลโก้ Shrine's
คอมโพเนนต์ MDC Android ใน Codelab นี้
- ช่องข้อความ
- ปุ่ม
สิ่งที่ต้องมี
- ความรู้เบื้องต้นเกี่ยวกับการพัฒนา Android
- Android Studio (ดาวน์โหลดได้ที่นี่หากยังไม่มี)
- โปรแกรมจําลองหรืออุปกรณ์ Android (พร้อมใช้งานผ่าน Android Studio)
- โค้ดตัวอย่าง (ดูขั้นตอนถัดไป)
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Android ในระดับใด
เริ่มต้นใช้งาน Android Studio
เมื่อเปิด Android Studio แอปควรจะแสดงหน้าต่างชื่อ "ยินดีต้อนรับสู่ Android Studio" อย่างไรก็ตาม หากเปิดตัว Android Studio เป็นครั้งแรก ให้ทําตามขั้นตอนวิซาร์ดการตั้งค่า Android Studio โดยใช้ค่าเริ่มต้น ขั้นตอนนี้อาจใช้เวลาหลายนาทีในการดาวน์โหลดและติดตั้งไฟล์ที่จําเป็น ดังนั้นโปรดปล่อยทิ้งไว้ในเบื้องหลังขณะทํางานในส่วนถัดไป
ดาวน์โหลดแอป Starter Lab
แอปเริ่มต้นจะอยู่ในไดเรกทอรี material-components-android-codelabs-101-starter/kotlin
...หรือโคลนจาก GitHub
หากต้องการโคลน Codelab นี้จาก GitHub ให้เรียกใช้คําสั่งต่อไปนี้
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 101-starter
โหลดโค้ดเริ่มต้นใน Android Studio
- เมื่อวิซาร์ดการตั้งค่าเสร็จสิ้นและหน้าต่างยินดีต้อนรับสู่ Android Studio ปรากฏขึ้น ให้คลิกเปิดโครงการ Android Studio ที่มีอยู่ ไปที่ไดเรกทอรีที่ติดตั้งโค้ดตัวอย่าง แล้วเลือก kotlin ->ศาลเจ้า(หรือค้นหาศาลเจ้าในคอมพิวเตอร์ของคุณ) เพื่อเปิดโปรเจ็กต์การจัดส่ง
- รอสักครู่เพื่อให้ Android Studio สร้างและซิงค์โปรเจ็กต์ดังที่แสดงตามสัญญาณบอกสถานะกิจกรรมที่ด้านล่างของหน้าต่าง Android Studio
- เมื่อถึงจุดนี้ Android Studio อาจแสดงข้อผิดพลาดบิลด์บางรายการเนื่องจากคุณไม่มี Android SDK หรือเครื่องมือสร้าง เช่น ดังที่แสดงด้านล่าง ทําตามวิธีการใน Android Studio เพื่อติดตั้ง/อัปเดตและซิงค์โปรเจ็กต์
เพิ่มทรัพยากร Dependency ของโปรเจ็กต์
โครงการต้องพึ่งพาไลบรารีการสนับสนุนของ Android สําหรับ MDC โค้ดตัวอย่างที่คุณดาวน์โหลดควรมีรายการทรัพยากร Dependency นี้อยู่แล้ว แต่เราขอแนะนําให้ทําตามขั้นตอนต่อไปนี้เพื่อให้แน่ใจว่า
- ไปที่ไฟล์
build.gradle
ของโมดูลapp
##39; และตรวจสอบว่าบล็อกdependencies
มีทรัพยากร Dependency ใน MDC ของ Android ดังนี้
api 'com.google.android.material:material:1.1.0-alpha06'
- (ไม่บังคับ) หากจําเป็น ให้แก้ไขไฟล์
build.gradle
เพื่อเพิ่มทรัพยากร Dependency ต่อไปนี้และซิงค์โปรเจ็กต์
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' }
เรียกใช้แอปเริ่มต้น
|
สำเร็จ! โค้ดเริ่มต้นสําหรับหน้าเข้าสู่ระบบของ Shrine ควรอยู่ในโปรแกรมจําลองของคุณ คุณจะเห็นชื่อ "Shrine" และโลโก้ Shrine อยู่ด้านล่าง
มาดูโค้ดกัน เรามีเฟรมเวิร์กการนําทาง Fragment
ที่เรียบง่ายในโค้ดตัวอย่างสําหรับการแสดงส่วนย่อยและไปยังส่วนย่อย
เปิด MainActivity.kt
ในไดเรกทอรี shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine
ซึ่งควรมีสิ่งต่อไปนี้
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()
}
}
กิจกรรมนี้จะแสดงไฟล์เลย์เอาต์ R.layout.shr_main_activity
ที่กําหนดไว้ใน shr_main_activity.xml
คุณจะเห็นว่าใน onCreate(),
MainActivity.kt
เริ่มต้นธุรกรรม Fragment
เพื่อแสดง LoginFragment
สําหรับ Codelab นี้ เราจะแก้ไข LoginFragment
นอกจากนี้ กิจกรรมยังใช้เมธอด navigateTo(Fragment)
ซึ่งกําหนดไว้ใน NavigationHost
ซึ่งจะช่วยให้ส่วนย่อยใดก็ตามไปยังส่วนย่อยที่แตกต่างกันได้
Command + คลิก (หรือ Control + คลิก) shr_main_activity
ในไฟล์กิจกรรมเพื่อเปิดไฟล์เลย์เอาต์หรือไปยังไฟล์เลย์เอาต์ใน 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"/>
ในส่วนนี้ เราจะเห็น <FrameLayout>
ที่เรียบง่ายซึ่งทําหน้าที่เป็นคอนเทนเนอร์สําหรับส่วนย่อยของกิจกรรมต่างๆ
ต่อไป มาเปิด 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
จะขยายไฟล์เลย์เอาต์ shr_login_fragment
และแสดงใน onCreateView()
คราวนี้มาดูที่ไฟล์เลย์เอาต์ shr_login_fragment.xml
เพื่อดูว่าหน้าเข้าสู่ระบบมีลักษณะอย่างไร
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>
ในที่นี้คุณจะเห็น <LinearLayout>
โดยมี <ImageView>
ที่ด้านบนซึ่งแสดงถึงโลโก้ศาลเจ้า
หลังจากนั้นจะมีแท็ก <TextView>
ที่แทนป้ายกํากับศาลเจ้าใต้โลโก้ ข้อความสําหรับป้ายกํากับนี้เป็นทรัพยากรสตริงชื่อ @string/shr_app_name
หากคําสั่ง + คลิก (หรือControl + คลิก) ชื่อทรัพยากรสตริง หรือเปิด app -> res -> values -> strings.xml
คุณจะเห็นไฟล์ strings.xml
ที่มีการกําหนดทรัพยากรสตริง เมื่อมีการเพิ่มทรัพยากรสตริงมากขึ้นในอนาคต ระบบจะกําหนดทรัพยากรที่นี่ ทรัพยากรทุกรายการในไฟล์นี้ควรมีคํานําหน้า shr_
เพื่อระบุว่าทรัพยากรเหล่านี้เป็นส่วนหนึ่งของแอปศาลเจ้า
เมื่อคุณคุ้นเคยกับโค้ดเริ่มต้นแล้ว มานําคอมโพเนนต์แรกของเราไปใช้กัน
ในขั้นเริ่มต้น เราจะเพิ่มช่องข้อความ 2 ช่องลงในหน้าการเข้าสู่ระบบเพื่อให้ผู้คนป้อนชื่อผู้ใช้และรหัสผ่าน เราจะใช้คอมโพเนนต์ช่องข้อความ MDC ที่มีฟังก์ชันในตัวซึ่งแสดงป้ายกํากับแบบลอยและข้อความแสดงข้อผิดพลาด
เพิ่ม XML
ใน shr_login_fragment.xml
ให้เพิ่มองค์ประกอบ TextInputLayout
ที่มี TextInputEditText
ย่อยภายใน <LinearLayout>
ใต้ป้ายกํากับ "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>
ข้อมูลโค้ดข้างต้นแสดงช่องข้อความ 2 ช่อง โดยแต่ละช่องจะประกอบด้วยองค์ประกอบ <TextInputLayout>
และองค์ประกอบย่อย <TextInputEditText>
ข้อความคําแนะนําสําหรับช่องข้อความแต่ละช่องจะระบุอยู่ในแอตทริบิวต์ android:hint
เราได้รวมทรัพยากรสตริงใหม่ 2 รายการสําหรับช่องข้อความ ได้แก่ @string/shr_hint_username
และ @string/shr_hint_password
เปิด strings.xml
เพื่อดูทรัพยากรสตริงเหล่านี้
strings.xml
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
เพิ่มการตรวจสอบการป้อนข้อมูล
คอมโพเนนต์ TextInputLayout
มีฟังก์ชันการแสดงความคิดเห็นแสดงข้อผิดพลาดในตัว
ทําการเปลี่ยนแปลง shr_login_fragment.xml
เพื่อแสดงความคิดเห็นในข้อผิดพลาด
- ตั้งค่าแอตทริบิวต์
app:errorEnabled
เป็นtrue
ในองค์ประกอบรหัสผ่านTextInputLayout
ซึ่งจะเพิ่มระยะห่างจากขอบสําหรับข้อความแสดงข้อผิดพลาดใต้ช่องข้อความ - ตั้งค่าแอตทริบิวต์
android:inputType
เป็น "textPassword
" ในองค์ประกอบรหัสผ่านTextInputEditText
การดําเนินการนี้จะซ่อนข้อความที่ป้อนในช่องรหัสผ่าน
จากการเปลี่ยนแปลงเหล่านี้ ช่องข้อความใน shr_login_fragment.xml
ควรมีลักษณะดังนี้
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>
คราวนี้ลองเรียกใช้แอป คุณจะเห็นหน้าที่มีช่องข้อความ 2 ช่องสําหรับ "ชื่อผู้ใช้" และ "รหัสผ่าน"
ลองดูภาพเคลื่อนไหวของป้ายกํากับแบบลอย
ต่อไป เราจะเพิ่มปุ่ม 2 ปุ่มลงในหน้าเข้าสู่ระบบของเรา ได้แก่ "Cancel" &"Next&" เราจะใช้คอมโพเนนต์ปุ่ม MDC ที่มาพร้อมกับเอฟเฟกต์ระแนงหมึกจาก Material Design ในตัว
เพิ่ม XML
ใน shr_login_fragment.xml
ให้เพิ่ม <RelativeLayout>
ลงใน <LinearLayout>
ใต้องค์ประกอบ TextInputLayout
จากนั้นเพิ่มองค์ประกอบ <MaterialButton>
2 รายการลงใน <RelativeLayout>
ไฟล์ XML ที่ได้ควรมีลักษณะดังนี้
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>
เท่านี้ก็เรียบร้อย เมื่อคุณเรียกใช้แอป คลื่นหมึกจะแสดงเมื่อคุณแตะปุ่มแต่ละปุ่ม
สุดท้ายเราจะเพิ่มโค้ด Kotlin ลงใน LoginFragment.kt
เพื่อแสดงปุ่ม "Next" ของเราเพื่อให้เปลี่ยนไปใช้ส่วนย่อยอื่นได้
มาเพิ่มเมธอดบูลีน isPasswordValid
ส่วนตัวใน LoginFragment.kt
ใต้ onCreateView()
โดยใช้ตรรกะในการพิจารณาว่ารหัสผ่านถูกต้องหรือไม่ สําหรับการสาธิตนี้ เราเพียงต้องดูว่ารหัสผ่านมีความยาวอย่างน้อย 8 อักขระ:
LoginFragment.kt
private fun isPasswordValid(text: Editable?): Boolean {
return text != null && text.length >= 8
}
จากนั้นให้เพิ่ม Listener การคลิกลงในปุ่ม "Next" ที่ตั้งค่าและล้างข้อผิดพลาดตามเมธอด isPasswordValid()
ที่เราเพิ่งสร้างขึ้น ใน onCreateView()
ควรวาง Listener การคลิกนี้ระหว่างเส้นเป่าลมและเส้น return view
มาเพิ่ม Listener รหัสผ่านลงในรหัสผ่าน TextInputEditText
เพื่อฟังเหตุการณ์สําคัญที่จะช่วยล้างข้อผิดพลาดกัน Listener นี้ควรใช้ isPasswordValid()
เพื่อตรวจสอบว่ารหัสผ่านถูกต้องหรือไม่ คุณเพิ่มข้อมูลนี้ใต้ Listener การคลิกใน onCreateView()
ได้โดยตรง
ตอนนี้เมธอด onCreateView() ควรมีลักษณะดังนี้
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
}
}
ตอนนี้เราจะไปยังส่วนย่อยอื่นได้แล้ว ใน onCreateView()
ให้อัปเดต OnClickListener
เพื่อไปยังส่วนอื่นเมื่อการตรวจสอบข้อผิดพลาดสําเร็จ รหัส clickListener
ควรมีลักษณะดังนี้
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)
}
})
เราได้เพิ่มบรรทัด (
activity
as
NavigationHost).navigateTo(ProductGridFragment(),
false
)
ลงในเคส else
ของ Listener การคลิก บรรทัดนี้จะเรียกใช้เมธอด navigateTo()
จาก MainActivity
เพื่อไปยังส่วนใหม่ -- ProductGridFragment
ปัจจุบันหน้านี้เป็นหน้าว่างเพื่อให้คุณใช้ใน MDC-102
เริ่มสร้างแอปได้เลย กดปุ่มถัดไป
คุณได้แลกรางวัลแล้ว! หน้าจอนี้จะเป็นจุดเริ่มต้นของ Codelab ถัดไปของเรา ซึ่งคุณจะทํางานใน MDC-102
การใช้คอมโพเนนต์ XML พื้นฐานและ Kotlin ประมาณ 30 บรรทัดช่วยให้ไลบรารี Material Components สําหรับ Android สร้างหน้าเข้าสู่ระบบที่สวยงามซึ่งสอดคล้องกับหลักเกณฑ์การออกแบบ Material รวมถึงยังคงดูและทํางานได้อย่างสม่ําเสมอในทุกอุปกรณ์
ขั้นตอนถัดไป
ช่องข้อความและปุ่มเป็นองค์ประกอบหลัก 2 อย่างในไลบรารี Android ของ MDC แต่ยังมีอีกหลายองค์ประกอบ คุณจะสํารวจส่วนที่เหลือของคอมโพเนนต์ใน MDC บน Android ได้ หรือจะไปที่ MDC 102: การออกแบบและเลย์เอาต์ของ Material Design เพื่อดูข้อมูลเกี่ยวกับแถบแอปด้านบน มุมมองการ์ด และเลย์เอาต์ของตารางกริด ขอขอบคุณที่ลองใช้คอมโพเนนต์วัสดุ หวังว่าคุณจะชอบ Codelab นี้