Material Components (MDC) ช่วยให้นักพัฒนาซอฟต์แวร์นํา Material Design ไปใช้ได้ MDC สร้างโดยทีมวิศวกรและนักออกแบบ UX ที่ Google มีคอมโพเนนต์ UI ที่สวยงามและใช้งานได้จํานวนมาก และพร้อมใช้งานสําหรับ Android, iOS, เว็บ และ Flitter material.io/develop |
ใน Codelab MDC-101 คุณใช้ Material Components (MDC) 2 รายการเพื่อสร้างหน้าเข้าสู่ระบบ ซึ่งก็คือช่องข้อความและปุ่ม ทีนี้เรามาขยายรากฐานนี้โดยเพิ่มการนําทาง โครงสร้าง และข้อมูลกัน
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะต้องสร้างหน้าจอหลักสําหรับแอปชื่อ Shrine ซึ่งเป็นแอปอีคอมเมิร์ซที่ขายเสื้อผ้าและของใช้ในบ้าน ซึ่งประกอบด้วย
- แถบแอปด้านบน
- รายการผลิตภัณฑ์แบบตารางกริด
คอมโพเนนต์ MDC-Android ใน Codelab นี้
- เลย์เอาต์แอป
- มุมมอง Material Material
สิ่งที่ต้องมี
- ความรู้เบื้องต้นเกี่ยวกับการพัฒนา Android
- Android Studio (ดาวน์โหลดได้ที่นี่หากยังไม่มี)
- โปรแกรมจําลองหรืออุปกรณ์ Android (พร้อมใช้งานผ่าน Android Studio)
- โค้ดตัวอย่าง (ดูขั้นตอนถัดไป)
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Android ในระดับใด
การดําเนินการต่อจาก MDC-101
หากคุณกรอก MDC-101 เสร็จ โค้ดของคุณควรพร้อมใช้งานสําหรับ Codelab นี้ คุณสามารถข้ามไปยังขั้นตอนที่ 3: เพิ่มแถบแอปยอดนิยม
เริ่มต้นใหม่ทั้งหมด
ดาวน์โหลดแอป Starter Lab
แอปเริ่มต้นจะอยู่ในไดเรกทอรี material-components-android-codelabs-102-starter/java
ตรวจสอบว่าได้ cd
ในไดเรกทอรีนั้นก่อนเริ่มต้น
...หรือโคลนจาก GitHub
หากต้องการโคลน Codelab นี้จาก 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 ที่มีอยู่ ไปที่ไดเรกทอรีที่ติดตั้งโค้ดตัวอย่าง แล้วเลือก java ->ศาลเจ้า (หรือค้นหา shrine) ในคอมพิวเตอร์เพื่อเปิดโปรเจ็กต์ศาลเจ้า
- รอสักครู่เพื่อให้ 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' }
เรียกใช้แอปเริ่มต้น
|
สำเร็จ! คุณจะเห็นหน้าการเข้าสู่ระบบศาลเจ้าจาก Codelab ของ MDC-101
เมื่อหน้าจอเข้าสู่ระบบดูดีแล้ว ให้ป้อนข้อมูลแอปด้วยผลิตภัณฑ์บางอย่าง
หน้าจอหลักจะแสดงเมื่อมีการปิดหน้าเข้าสู่ระบบด้วยหน้าจอที่ระบุว่า "คุณทําได้!" เยี่ยมเลย! แต่ตอนนี้ผู้ใช้ของเราไม่มีการดําเนินการหรือดําเนินการใดๆ ในแอปแล้ว มาช่วยให้ผู้ใช้เพิ่มการนําทางได้ง่ายขึ้น
การออกแบบเนื้อหานําเสนอรูปแบบการนําทางที่ช่วยให้มั่นใจว่าจะมีความสามารถในการใช้งานสูง หนึ่งในองค์ประกอบการนําทางที่สําคัญที่สุดคือแถบแอปด้านบน
ในการนําทางและให้ผู้ใช้เข้าถึงการดําเนินการอื่นๆ ได้อย่างรวดเร็ว มาเพิ่มแถบแอปยอดนิยมกัน
เพิ่มวิดเจ็ต 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 ว่าปุ่มการทํางาน
เราจะจัดรูปแบบแถบแอปด้านบนและเพิ่มปุ่มการทํางานลงในเมนูแบบเป็นโปรแกรม
ขั้นแรก เราจะสร้างวิธีตั้งค่าแถบเครื่องมือกัน เมธอดควรได้รับการอ้างอิงไปยังแถบเครื่องมือโดยใช้ id
และยังได้รับการอ้างอิงเกี่ยวกับกิจกรรมโดยใช้ getActivity()
ด้วย หากกิจกรรมไม่เป็นค่าว่าง ให้ตั้งค่า Toolbar
เป็น ActionBar
โดยใช้ setSupportActionBar
ProductGridFragment.java
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
ถัดไป ใต้วิธีการ setUpToolbar
เราเพิ่งเพิ่ม มาแทนที่ onCreateOptionsMenu
เพื่อเพิ่มเนื้อหาของ shr_toolbar_menu.xml
ในแถบเครื่องมือให้สูงเกินจริง ดังนี้
ProductGridFragment.java
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
และเพิ่มการเรียกเมธอด setUpToolbar
ไปยังเนื้อหาของเมธอด onCreateView()
พร้อมข้อมูลต่อไปนี้
ProductGridFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
สุดท้าย เพิ่มเมธอด onCreate()
ใน ProductGridFragment.java
ในเนื้อหาของเมธอด ให้ตั้งค่าพารามิเตอร์ของ setHasOptionMenu
เป็น true
วิธีการควรมีลักษณะดังนี้
ProductGridFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
โค้ดด้านบนตั้งค่าแถบแอปจากเลย์เอาต์ XML เป็นแถบการดําเนินการสําหรับกิจกรรมนี้ โค้ดเรียกกลับ onCreateOptionsMenu
จะบอกกิจกรรมที่จะใช้เป็นเมนูของเรา ในกรณีนี้ ก็จะนํารายการในเมนูจาก R.menu.shr_toolbar_menu
ไปไว้ในแถบแอป
ไฟล์เมนูประกอบด้วย 2 รายการ ได้แก่ "Search" และ "Filter"
เมนู shr_แถบเครื่องมือ_.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.java
ของคุณควรมีลักษณะดังต่อไปนี้
ProductGridFragment.java
package com.google.codelabs.mdc.java.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 android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
สร้างและเรียกใช้ หน้าจอหลักควรมีลักษณะดังนี้
ตอนนี้แถบเครื่องมือจะมีไอคอนการนําทาง ชื่อ และไอคอนการทํางาน 2 ไอคอนอยู่ทางด้านขวา นอกจากนี้ แถบเครื่องมือยังจะแสดงระดับความสูงโดยใช้เงาเล็กๆ น้อยๆ ซึ่งแสดงชั้นในเลเยอร์ที่แตกต่างจากเนื้อหา
ถึงตอนนี้ แอปของเรามีโครงสร้างบางอย่าง มาจัดระเบียบเนื้อหาด้วยการวางไว้ในการ์ดกัน
เพิ่มบัตร
มาเริ่มกันที่การเพิ่มการ์ด 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>
สร้างและเรียกใช้
ในหน้าตัวอย่างนี้จะเห็นว่าการ์ดเข้าอยู่ในขอบขอบซ้ายของหน้าจอ และมีมุมโค้งมนและเงา (ซึ่งจะแสดงความสูงของการ์ด) พื้นที่ทั้งหมดเรียกว่า "container." นอกจากคอนเทนเนอร์ในตัวแล้ว องค์ประกอบทั้งหมดภายในคอนเทนเนอร์ก็เป็นองค์ประกอบที่ไม่บังคับ
คุณเพิ่มองค์ประกอบต่อไปนี้ในคอนเทนเนอร์ได้ ไม่ว่าจะเป็นข้อความส่วนหัว ภาพขนาดย่อหรือรูปโปรไฟล์ ข้อความส่วนหัวย่อย เส้นแบ่ง รวมถึงปุ่มและไอคอน เช่น การ์ดที่เพิ่งสร้างขึ้นมี TextView
อยู่ 2 รายการ (อย่างละ 1 สําหรับชื่อ และ 1 ข้อความสําหรับรอง) ใน LinearLayout
ซึ่งสอดคล้องกับด้านล่างของการ์ด
ปกติแล้วการ์ดจะแสดงในคอลเล็กชันที่มีการ์ดอื่นๆ ในส่วนถัดไปของ Codelab นี้ เราจะจัดคอลเล็กชันดังกล่าวเป็นตารางกริดในตารางกริด
เมื่อมีการ์ดหลายใบแสดงในหน้าจอ การ์ดเหล่านั้นจะรวมกันเป็นคอลเล็กชันอย่างน้อย 1 คอลเล็กชัน การ์ดในตารางกริดเป็นระนาบเดียวกัน ซึ่งหมายความว่าใช้ระดับระดับความสูงขณะพักเดียวกันกับกันและกัน (เว้นแต่จะหยิบหรือลากไป แต่เราจะไม่พูดถึงใน Codelab นี้)
ตั้งค่าตารางกริดของการ์ด
ดูไฟล์ 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.java
package com.google.codelabs.mdc.java.shrine;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.codelabs.mdc.java.shrine.network.ImageRequester;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
import java.util.List;
/**
* Adapter used to show a simple grid of products.
*/
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {
private List<ProductEntry> productList;
private ImageRequester imageRequester;
ProductCardRecyclerViewAdapter(List<ProductEntry> productList) {
this.productList = productList;
imageRequester = ImageRequester.getInstance();
}
@NonNull
@Override
public ProductCardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.shr_product_card, parent, false);
return new ProductCardViewHolder(layoutView);
}
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
// TODO: Put ViewHolder binding code here in MDC-102
}
@Override
public int getItemCount() {
return productList.size();
}
}
คลาสอะแดปเตอร์ด้านบนจะจัดการเนื้อหาของตารางกริด ในเร็วๆ นี้เราจะเขียนโค้ดสําหรับ onBindViewHolder()
เพื่อพิจารณาว่าควรดําเนินการอย่างไรกับเนื้อหาแต่ละรายการ
และคุณยังดู ProductCardViewHolder
ในแพ็กเกจเดียวกันได้ด้วย คลาสนี้จะจัดเก็บการดูที่ส่งผลต่อเลย์เอาต์การ์ดของเรา เพื่อให้คุณแก้ไขในภายหลังได้
ProductCardViewholder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
// TODO: Find and store views from itemView
}
}
ในการตั้งค่าตารางกริด เราจะนําตัวยึดตําแหน่ง MaterialCardView
ออกจาก shr_product_grid_fragment.xml
ก่อน จากนั้น คุณควรเพิ่มคอมโพเนนต์ที่แสดงตารางของการ์ด ในกรณีนี้ ให้เพิ่มคอมโพเนนต์ 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.java
หลังจากเรียกใช้ setUpToolbar(view)
และก่อนคําสั่ง return
ProductGridFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
ข้อมูลโค้ดข้างต้นมีขั้นตอนเริ่มต้นที่จําเป็นเพื่อตั้งค่า RecyclerView
ซึ่งรวมถึงการตั้งค่าตัวจัดการเลย์เอาต์ RecyclerView
', การเริ่มต้นใช้งาน และการตั้งค่าอะแดปเตอร์ RecyclerView
'
ตอนนี้ไฟล์ ProductGridFragment.java
ควรมีลักษณะดังนี้
ProductGridFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
สร้างและเรียกใช้
การ์ดมาแล้ว พวกเขายังไม่แสดงอะไรเลย มาเพิ่มข้อมูลผลิตภัณฑ์กัน
เพิ่มรูปภาพและข้อความ
เพิ่มรูปภาพ ชื่อผลิตภัณฑ์ และราคาสําหรับแต่ละการ์ด นามธรรม ViewHolder
ของเราจะเก็บรักษายอดดูของการ์ดแต่ละใบ ใน ViewHolder
ให้เพิ่มข้อมูลพร็อพเพอร์ตี้ 3 รายการดังนี้
ProductCardViewholder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.volley.toolbox.NetworkImageView;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView productImage;
public TextView productTitle;
public TextView productPrice;
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productPrice = itemView.findViewById(R.id.product_price);
}
}
ในอะแดปเตอร์ RecyclerView
's ของเรา ใน ViewHolder,
ให้อัปเดตเมธอด onBindViewHolder()
เพื่อตั้งค่าข้อมูลของแต่ละมุมมอง:
ProductCardRecyclerViewAdapter.java
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
if (productList != null && position < productList.size()) {
ProductEntry product = productList.get(position);
holder.productTitle.setText(product.title);
holder.productPrice.setText(product.price);
imageRequester.setImageFromUrl(holder.productImage, product.url);
}
}
โค้ดด้านบนจะบอกให้อะแดปเตอร์ของ RecyclerView
ทราบว่าต้องทําอย่างไรกับบัตรแต่ละใบโดยใช้ ViewHolder
การดําเนินการนี้จะตั้งค่าข้อมูลข้อความในแต่ละ TextView
ของ ViewHolder
และเรียก ImageRequester
เพื่อรับรูปภาพจาก URL ImageRequester
คือชั้นเรียนที่เราจัดให้ไว้เพื่อความสะดวกของคุณ และใช้ไลบรารี Volley
(เป็นหัวข้อที่ไม่อยู่ในขอบเขตของ Codelab นี้ แต่คุณสามารถสํารวจโค้ดด้วยตนเองได้)
สร้างและเรียกใช้
ผลิตภัณฑ์ของเราจะปรากฏในแอปแล้ว
แอปของเรามีขั้นตอนพื้นฐานที่นําผู้ใช้ไปยังหน้าจอการเข้าสู่ระบบไปยังหน้าจอหลัก ซึ่งคุณจะดูผลิตภัณฑ์ได้ เพียงใส่โค้ดแอปเพียง 2-3 บรรทัด เราได้เพิ่มแถบแอปยอดนิยมพร้อมด้วยชื่อและปุ่ม 3 ปุ่ม รวมถึงตารางของการ์ดเพื่อนําเสนอเนื้อหาของแอป ตอนนี้หน้าจอหลักของเราใช้งานง่ายและเรียบง่าย มีโครงสร้างพื้นฐานและเนื้อหาที่นําไปใช้ได้จริง
ขั้นตอนถัดไป
ตอนนี้ด้วยแถบแอป การ์ด ช่องข้อความ และปุ่มด้านบน ตอนนี้เราได้ใช้องค์ประกอบหลัก 4 อย่างของ Material Design จากไลบรารี MDC-Android คุณสามารถสํารวจคอมโพเนนต์เพิ่มเติมได้ในคอมโพเนนต์ของ MDC-Android ใน MDC Android
แม้ว่าแอปจะทํางานได้อย่างสมบูรณ์ แต่แอปของเราก็ยังไม่แสดงแบรนด์ที่เฉพาะเจาะจง ใน MDC-103: ธีม Material Design ด้วยสี รูปร่าง ความสูง และประเภท เราจะปรับแต่งสไตล์ของคอมโพเนนต์เหล่านี้เพื่อสื่อถึงแบรนด์ที่มีความทันสมัยและมีชีวิตชีวา