1. บทนำ
Material Components (MDC) ช่วยให้นักพัฒนานำดีไซน์ Material มาใช้ MDC สร้างขึ้นโดยทีมวิศวกรและนักออกแบบ UX จาก Google โดยมีคอมโพเนนต์ UI ที่สวยงามและใช้งานได้จริงหลายสิบรายการ และพร้อมใช้งานสำหรับ Android, iOS, เว็บ และ Flutter ที่ material.io/develop |
ใน Codelab MDC-101 คุณใช้คอมโพเนนต์ Material (MDC) 2 รายการเพื่อสร้างหน้าเข้าสู่ระบบ ได้แก่ ช่องข้อความและปุ่มที่มีลายน้ำ ตอนนี้มาขยายฐานรากนี้ด้วยการเพิ่มการนําทาง โครงสร้าง และข้อมูล
สิ่งที่คุณจะสร้าง
ในโค้ดแล็บนี้ คุณจะได้สร้างหน้าจอหลักสําหรับแอปชื่อ Shrine ซึ่งเป็นแอปอีคอมเมิร์ซที่ขายเสื้อผ้าและของใช้ในบ้าน โดยจะมีข้อมูลต่อไปนี้
- แถบแอปด้านบน
- รายการตารางกริดที่เต็มไปด้วยผลิตภัณฑ์
คอมโพเนนต์ MDC-Android ใน Codelab นี้
- AppBarLayout
- MaterialCardView
สิ่งที่ต้องมี
- ความรู้พื้นฐานเกี่ยวกับการพัฒนาแอป Android
- Android Studio (ดาวน์โหลดที่นี่หากยังไม่มี)
- โปรแกรมจำลองหรืออุปกรณ์ Android (มีให้ใช้งานผ่าน Android Studio)
- โค้ดตัวอย่าง (ดูขั้นตอนถัดไป)
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Android ของคุณในระดับใด
2. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์
หากต้องการดูต่อจาก MDC-101
หากคุณดำเนินการ MDC-101 เสร็จสมบูรณ์แล้ว คุณควรเตรียมโค้ดสำหรับ Codelab นี้ ข้ามไปที่ขั้นตอนที่ 3: เพิ่มแถบแอปด้านบน
หากเพิ่งเริ่มต้น
ดาวน์โหลดแอป Codelab เริ่มต้น
แอปเริ่มต้นอยู่ในไดเรกทอรี material-components-android-codelabs-102-starter/kotlin
อย่าลืมcd
เข้าไปในไดเรกทอรีนั้นก่อนเริ่มต้น
...หรือโคลนโมเดลจาก GitHub
หากต้องการโคลนโค้ดแล็บนี้จาก GitHub ให้เรียกใช้คำสั่งต่อไปนี้
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 102-starter
โหลดโค้ดเริ่มต้นใน Android Studio
- เมื่อวิซาร์ดการตั้งค่าเสร็จสิ้นและหน้าต่างยินดีต้อนรับสู่ Android Studio ปรากฏขึ้น ให้คลิกเปิดโปรเจ็กต์ Android Studio ที่มีอยู่ ไปที่ไดเรกทอรีที่คุณติดตั้งโค้ดตัวอย่างไว้ แล้วเลือก kotlin ->คำบรรยาย (หรือค้นหา shrine ในคอมพิวเตอร์) เพื่อเปิดโปรเจ็กต์การจัดส่ง
- รอสักครู่เพื่อให้ Android Studio สร้างและซิงค์โปรเจ็กต์ ตามที่ตัวบ่งชี้กิจกรรมที่ด้านล่างของหน้าต่าง Android Studio แสดง
- ณ จุดนี้ Android Studio อาจแสดงข้อผิดพลาดบางอย่างในเวอร์ชันเนื่องจากคุณไม่มี Android SDK หรือเครื่องมือสร้างบิลด์ ดังเช่นตัวอย่างด้านล่าง ทำตามวิธีการใน Android Studio เพื่อติดตั้ง/อัปเดตโปรเจ็กต์เหล่านี้ และซิงค์โปรเจ็กต์
เพิ่มทรัพยากร Dependency ของโปรเจ็กต์
โปรเจ็กต์ต้องอาศัยไลบรารีการสนับสนุน Android ของ MDC โค้ดตัวอย่างที่คุณดาวน์โหลดควรมีรายการนี้อยู่แล้ว แต่คุณควรทำตามขั้นตอนต่อไปนี้เพื่อตรวจสอบ
- ไปที่ไฟล์
build.gradle
ของโมดูลapp
และตรวจสอบว่าบล็อกdependencies
มีการพึ่งพา 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 จาก Codelab ของ MDC-101
เมื่อหน้าจอการเข้าสู่ระบบดูดีแล้ว เรามาเพิ่มผลิตภัณฑ์ลงในแอปกัน
3. เพิ่มแถบแอปด้านบน
หน้าจอหลักจะปรากฏขึ้นเมื่อปิดหน้าลงชื่อเข้าใช้ โดยมีหน้าจอที่ระบุว่า "คุณทำได้แล้ว" เยี่ยมเลย แต่ตอนนี้ผู้ใช้ไม่ได้ดำเนินการใดๆ หรือคิดว่าตัวเองอยู่ที่ใดในแอป ตอนนี้ก็ถึงเวลาเพิ่มการนำทางแล้ว
Material Design มีรูปแบบการนําทางที่ช่วยให้ใช้งานได้ง่าย องค์ประกอบที่มองเห็นได้มากที่สุดอย่างหนึ่งคือแถบแอปด้านบน
มาเพิ่มแถบแอปด้านบนกัน เพื่อให้สามารถนำทางและให้ผู้ใช้เข้าถึงการทำงานอื่นๆ ได้อย่างรวดเร็ว
เพิ่มวิดเจ็ต AppBar
ใน shr_product_grid_fragment.xml
ให้ลบบล็อก <LinearLayout>
ที่มีข้อความ "คุณทำได้แล้ว!" TextView
และแทนที่ด้วยค่าต่อไปนี้
shr_product_grid_fragment.xml
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
ตอนนี้ shr_product_grid_fragment.xml
ควรมีลักษณะดังนี้
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
แถบแอปจำนวนมากมีปุ่มอยู่ข้างชื่อ มาเพิ่มไอคอนเมนูกัน
เพิ่มไอคอนการนำทาง
ขณะยังอยู่ใน shr_product_grid_fragment.xml
ให้เพิ่มข้อมูลต่อไปนี้ลงในคอมโพเนนต์ XML Toolbar
ที่คุณเพิ่งเพิ่มลงในเลย์เอาต์
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
shr_product_grid_fragment.xml
ของคุณควรมีลักษณะดังนี้
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
เพิ่มปุ่มการทำงานและจัดสไตล์แถบแอปด้านบน
นอกจากนี้ คุณยังเพิ่มปุ่มที่ด้านท้ายของแถบแอปได้ด้วย ใน Android เรียกปุ่มเหล่านี้ว่าปุ่มดำเนินการ เราจะจัดสไตล์แถบแอปด้านบนและเพิ่มปุ่มการดำเนินการลงในเมนูด้วยโปรแกรม
ในฟังก์ชัน onCreateView
ของ ProductGridFragment.kt
ให้ตั้งค่า Toolbar
ของ activity
ให้ใช้เป็น ActionBar
โดยใช้ setSupportActionBar
คุณทําได้หลังจากสร้างข้อมูลพร็อพเพอร์ตี้แล้วด้วย inflater
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
ถัดไป ใต้เมธอดที่เราเพิ่งเปลี่ยนเพื่อตั้งค่าแถบเครื่องมือ ให้ลบล้าง onCreateOptionsMenu
เพื่อขยายเนื้อหาของ shr_toolbar_menu.xml
ลงในแถบเครื่องมือ ดังนี้
ProductGridFragment.kt
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
สุดท้าย ให้ลบล้าง onCreate()
ใน ProductGridFragment.kt
และหลังจากโทรหา super()
แล้ว ให้โทรหา setHasOptionMenu
ด้วย true
ProductGridFragment.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
ข้อมูลโค้ดข้างต้นตั้งค่าแถบแอปจากเลย์เอาต์ XML เป็นแถบการทำงานสำหรับกิจกรรมนี้ การติดต่อกลับ onCreateOptionsMenu
จะบอกกิจกรรมที่จะต้องใช้เป็นเมนู ในกรณีนี้ ระบบจะใส่รายการเมนูจาก R.menu.shr_toolbar_menu
ลงในแถบแอป ไฟล์เมนูมี 2 รายการ ได้แก่ "ค้นหา" และ "ตัวกรอง"
shr_toolbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/shr_search"
android:title="@string/shr_search_title"
app:showAsAction="always" />
<item
android:id="@+id/filter"
android:icon="@drawable/shr_filter"
android:title="@string/shr_filter_title"
app:showAsAction="always" />
</menu>
หลังจากการเปลี่ยนแปลงแล้ว ไฟล์ ProductGridFragment.kt
ของคุณควรมีลักษณะดังนี้
ProductGridFragment.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the tool bar
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
return view;
}
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
}
สร้างและเรียกใช้ หน้าจอหลักควรมีลักษณะดังนี้
ตอนนี้แถบเครื่องมือจะมีไอคอนการนำทาง ชื่อ และไอคอนการดำเนินการ 2 รายการทางด้านขวา แถบเครื่องมือยังแสดงระดับความสูงโดยใช้เงาเล็กน้อยที่แสดงให้เห็นว่าอยู่ในเลเยอร์อื่นนอกเหนือจากเนื้อหา
4. เพิ่มบัตร
เมื่อแอปมีโครงสร้างแล้ว เรามาจัดระเบียบเนื้อหาโดยวางไว้ในการ์ดกัน
เพิ่มบัตร
มาเริ่มกันด้วยการเพิ่มการ์ด 1 ใบใต้แถบแอปด้านบน การ์ดควรมีภูมิภาคสำหรับรูปภาพ ชื่อ และป้ายกำกับสำหรับข้อความรอง เพิ่มข้อมูลต่อไปนี้ใน shr_product_grid_fragment.xml
ใต้ AppBarLayout
shr_product_grid_fragment.xml
<com.google.android.material.card.MaterialCardView
android:layout_width="160dp"
android:layout_height="180dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="70dp"
app:cardBackgroundColor="?attr/colorPrimaryDark"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
สร้างและเรียกใช้
ในตัวอย่างนี้ คุณจะเห็นการ์ดถูกฝังจากขอบด้านซ้าย และมีมุมโค้งมนและเงา (ซึ่งแสดงระดับความสูงของการ์ด) องค์ประกอบทั้งหมดเรียกว่า "คอนเทนเนอร์" นอกจากคอนเทนเนอร์แล้ว องค์ประกอบทั้งหมดภายในคอนเทนเนอร์นั้นไม่บังคับ
คุณเพิ่มองค์ประกอบต่อไปนี้ลงในคอนเทนเนอร์ได้ ได้แก่ ข้อความส่วนหัว ภาพปกหรือรูปโปรไฟล์ ข้อความส่วนหัวย่อย ตัวแบ่ง และแม้แต่ปุ่มและไอคอน ตัวอย่างเช่น การ์ดที่เราเพิ่งสร้างขึ้นมี TextView
2 ตัว (อีกการ์ดหนึ่งสำหรับชื่อและอีกส่วนหนึ่งสำหรับข้อความรอง) ใน LinearLayout
ซึ่งจัดไว้ที่ด้านล่างของการ์ด
การ์ดมักจะแสดงในคอลเล็กชันร่วมกับการ์ดอื่นๆ ในส่วนถัดไปของ Codelab นี้ เราจะจัดวางเป็นคอลเล็กชันในตารางกริด
5. สร้างตารางกริดของการ์ด
เมื่อมีการ์ดหลายใบในหน้าจอเดียว ระบบจะจัดกลุ่มการ์ดเหล่านั้นเป็นคอลเล็กชันอย่างน้อย 1 รายการ การ์ดในตารางกริดจะอยู่ในระนาบเดียวกัน ซึ่งหมายความว่าการ์ดแต่ละใบจะมีระดับความสูงเดียวกัน (เว้นแต่จะมีการยกขึ้นหรือลากไป แต่เราจะไม่พูดถึงเรื่องนี้ในโค้ดแล็บนี้)
ตั้งค่าตารางกริดของการ์ด
โปรดดูไฟล์ shr_product_card.xml
ที่เราส่งให้คุณ
shr_product_card.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/product_image"
android:layout_width="match_parent"
android:layout_height="@dimen/shr_product_card_image_height"
android:background="?attr/colorPrimaryDark"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
เลย์เอาต์การ์ดนี้มีการ์ดที่มีรูปภาพ (ในกรณีนี้คือ NetworkImageView
ซึ่งช่วยให้เราโหลดและแสดงรูปภาพจาก URL ได้) และ TextViews
2 รูป
ถัดไป ลองดู ProductCardRecyclerViewAdapter
ที่เราเตรียมให้คุณ อยู่ในแพ็กเกจเดียวกับ ProductGridFragment
ProductCardRecyclerViewAdapter.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
/**
* Adapter used to show a simple grid of products.
*/
class ProductCardRecyclerViewAdapter(private val productList: List<ProductEntry>) : RecyclerView.Adapter<ProductCardViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductCardViewHolder {
val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.shr_product_card, parent, false)
return ProductCardViewHolder(layoutView)
}
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
// TODO: Put ViewHolder binding code here in MDC-102
}
override fun getItemCount(): Int {
return productList.size
}
}
คลาสอะแดปเตอร์ข้างต้นจะจัดการเนื้อหาของตารางกริด เราจะเขียนโค้ดสำหรับ onBindViewHolder()
ในเร็วๆ นี้เพื่อกำหนดว่ามุมมองแต่ละรายการควรทำอย่างไรกับเนื้อหาที่ระบุ
นอกจากนี้ คุณยังดู ProductCardViewHolder
ในแพ็กเกจเดียวกันได้ด้วย คลาสนี้จะจัดเก็บมุมมองที่ส่งผลต่อการจัดวางการ์ดของเรา เพื่อให้เราสามารถแก้ไขได้ในภายหลัง
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class ProductCardViewHolder(itemView: View) //TODO: Find and store views from itemView
: RecyclerView.ViewHolder(itemView)
ในการตั้งค่าตารางกริด ก่อนอื่นเราจะนำตัวยึดตำแหน่ง MaterialCardView
ออกจาก shr_product_grid_fragment.xml
ถัดไป คุณควรเพิ่มคอมโพเนนต์ที่แสดงตารางกริดของการ์ด ในกรณีนี้ เราจะใช้ RecyclerView เพิ่มคอมโพเนนต์ RecyclerView ลงใน shr_product_grid_fragment.xml
ใต้คอมโพเนนต์ XML AppBarLayout
:
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:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
shr_product_grid_fragment.xml
ของคุณควรมีลักษณะดังนี้
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
</FrameLayout>
สุดท้าย ใน onCreateView()
ให้เพิ่มโค้ดการเริ่มต้น RecyclerView
ลงใน ProductGridFragment.kt
หลังจากเรียกใช้ setUpToolbar(view)
และก่อนคำสั่ง return
ดังนี้
ProductGridFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))
return view;
}
ข้อมูลโค้ดด้านบนมีขั้นตอนการเริ่มต้นที่จำเป็นในการตั้งค่า RecyclerView
ซึ่งรวมถึงการตั้งค่าเครื่องมือจัดการรูปแบบของ RecyclerView
รวมถึงการเริ่มต้นและการตั้งค่าอะแดปเตอร์ของ RecyclerView
ตอนนี้ไฟล์ ProductGridFragment.kt
ควรมีลักษณะดังนี้
ProductGridFragment .kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.codelabs.mdc.kotlin.shrine.network.ProductEntry
import kotlinx.android.synthetic.main.shr_product_grid_fragment.view.*
class ProductGridFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment with the ProductGrid theme
val view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false)
// Set up the toolbar.
(activity as AppCompatActivity).setSupportActionBar(view.app_bar)
// Set up the RecyclerView
view.recycler_view.setHasFixedSize(true)
view.recycler_view.layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false)
val adapter = ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(resources))
view.recycler_view.adapter = adapter
val largePadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing)
val smallPadding = resources.getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small)
view.recycler_view.addItemDecoration(ProductGridItemDecoration(largePadding, smallPadding))
return view;
}
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
}
สร้างและเรียกใช้
บัตรพร้อมใช้งานแล้ว ยังไม่มีการแสดงข้อมูลใดๆ ดังนั้นเรามาเพิ่มข้อมูลผลิตภัณฑ์กัน
เพิ่มรูปภาพและข้อความ
เพิ่มรูปภาพ ชื่อผลิตภัณฑ์ และราคาสำหรับการ์ดแต่ละใบ ViewHolder
Abstraction ของเรามีมุมมองสำหรับการ์ดแต่ละใบ ใน ViewHolder
ให้เพิ่มมุมมอง 3 รายการดังนี้
ProductCardViewHolder.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.toolbox.NetworkImageView
class ProductCardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var productImage: NetworkImageView = itemView.findViewById(R.id.product_image)
var productTitle: TextView = itemView.findViewById(R.id.product_title)
var productPrice: TextView = itemView.findViewById(R.id.product_price)
}
อัปเดตเมธอด onBindViewHolder()
ใน ProductCardRecyclerViewAdapter
เพื่อตั้งชื่อ ราคา และรูปภาพผลิตภัณฑ์สำหรับการแสดงผลผลิตภัณฑ์แต่ละรายการดังที่แสดงด้านล่าง
ProductCardRecyclerViewAdapter.kt
override fun onBindViewHolder(holder: ProductCardViewHolder, position: Int) {
if (position < productList.size) {
val product = productList[position]
holder.productTitle.text = product.title
holder.productPrice.text = product.price
ImageRequester.setImageFromUrl(holder.productImage, product.url)
}
}
โค้ดด้านบนบอกอะแดปเตอร์ของ RecyclerView
ว่าต้องทําอย่างไรกับการ์ดแต่ละใบโดยใช้ ViewHolder
ซึ่งตรงนี้จะกำหนดข้อมูลข้อความบน TextView
แต่ละรายการของ ViewHolder
และเรียก ImageRequester
เพื่อรับรูปภาพจาก URL ImageRequester
เป็นชั้นเรียนที่เราจัดเตรียมไว้ให้เพื่อความสะดวกของคุณ และใช้ไลบรารี Volley
(หัวข้อที่อยู่นอกขอบเขตของ Codelab นี้ แต่คุณสามารถสำรวจโค้ดด้วยตนเองได้)
สร้างและเรียกใช้
ผลิตภัณฑ์ของเราแสดงในแอปแล้ว
6. สรุป
แอปของเรามีขั้นตอนพื้นฐานที่จะนำผู้ใช้จากหน้าจอเข้าสู่ระบบไปยังหน้าจอหลักที่แสดงผลิตภัณฑ์ได้ เพียงเขียนโค้ดเพียงไม่กี่บรรทัด เราได้เพิ่มแถบแอปด้านบนพร้อมชื่อและปุ่ม 3 ปุ่ม และตารางการ์ดเพื่อนำเสนอเนื้อหาของแอป ตอนนี้หน้าจอหลักของเราเรียบง่ายและใช้งานได้จริง ด้วยโครงสร้างพื้นฐานแบบพื้นฐานและเนื้อหาที่นำไปใช้ได้จริง
ขั้นตอนถัดไป
ตอนนี้เราใช้คอมโพเนนต์หลักของ Material Design 4 รายการจากไลบรารี MDC-Android แล้ว ได้แก่ แถบแอปด้านบน การ์ด ช่องข้อความ และปุ่ม คุณสำรวจคอมโพเนนต์เพิ่มเติมได้โดยไปที่แคตตาล็อก MDC-Android
แม้ว่าแอปจะใช้งานได้อย่างเต็มรูปแบบ แต่แอปของเรายังไม่แสดงแบรนด์หรือสไตล์ใดเป็นพิเศษ ใน MDC-103: ธีมการออกแบบ Material Design ด้วยสี รูปร่าง ระดับ และประเภท เราจะปรับแต่งสไตล์ของคอมโพเนนต์เหล่านี้เพื่อแสดงแบรนด์ที่มีชีวิตชีวาและทันสมัย