1. บทนำ
Material Components (MDC) ช่วยให้นักพัฒนานำดีไซน์ Material มาใช้ MDC สร้างโดยทีมวิศวกรและนักออกแบบ UX ที่ Google โดยมีคอมโพเนนต์ UI ที่สวยงามและใช้งานได้หลายสิบอย่างและพร้อมใช้งานสำหรับ Android, iOS, เว็บ และ Flutter.material.io/develop |
ใน Codelab MDC-103 คุณได้ปรับแต่งสี ระดับความสูง และตัวอักษรของ Material Components (MDC) เพื่อจัดรูปแบบแอปของคุณ
คอมโพเนนต์หนึ่งในระบบดีไซน์ Material ทำงานชุดหนึ่งที่กำหนดไว้ล่วงหน้าและมีลักษณะเฉพาะบางอย่าง เช่น ปุ่ม อย่างไรก็ตาม ปุ่มเป็นมากกว่าวิธีสำหรับให้ผู้ใช้ทำงาน แต่ยังเป็นการแสดงออกทางภาพของรูปร่าง ขนาด และสีที่ช่วยให้ผู้ใช้ทราบว่าเป็นการโต้ตอบ และจะมีบางอย่างเกิดขึ้นเมื่อมีการแตะหรือคลิก
หลักเกณฑ์ดีไซน์ Material จะอธิบายส่วนประกอบต่างๆ จากมุมมองของนักออกแบบ โดยจะอธิบายฟังก์ชันพื้นฐานต่างๆ ที่พร้อมให้ใช้งานในแพลตฟอร์มต่างๆ รวมถึงองค์ประกอบที่เป็นส่วนประกอบของแต่ละส่วน ตัวอย่างเช่น ฉากหลังประกอบด้วยเลเยอร์ย้อนกลับและเนื้อหา เลเยอร์หน้าและเนื้อหา กฎการเคลื่อนไหว และตัวเลือกการแสดงผล องค์ประกอบแต่ละอย่างเหล่านี้สามารถปรับแต่งตามความต้องการ กรณีการใช้งาน และเนื้อหาของแต่ละแอปได้ องค์ประกอบเหล่านี้โดยส่วนใหญ่จะเป็นการแสดงผล การควบคุม และฟังก์ชันแบบดั้งเดิมจาก SDK ของแพลตฟอร์มของคุณ
แม้ว่าหลักเกณฑ์ดีไซน์ Material จะระบุคอมโพเนนต์หลายรายการ แต่ก็มีเพียงบางส่วนที่เป็นตัวเลือกที่ดีสำหรับโค้ดที่นำมาใช้ใหม่ได้ ดังนั้นจึงไม่มีคอมโพเนนต์แบบนั้นใน MDC คุณสร้างประสบการณ์เหล่านี้ได้เองเพื่อให้ได้สไตล์ที่กำหนดเองสำหรับแอป โดยใช้โค้ดแบบดั้งเดิม
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะต้องเพิ่มฉากหลังไปยัง Shrine โดยจะกรองผลิตภัณฑ์ที่แสดงในตารางกริดแบบอสมมาตรตามหมวดหมู่ คุณจะใช้สิ่งต่อไปนี้
- รูปร่าง
- การเคลื่อนไหว
- คลาส Android SDK แบบดั้งเดิม
คอมโพเนนต์ MDC-Android ใน Codelab นี้
- รูปร่าง
สิ่งที่คุณต้องมี
- ความรู้พื้นฐานเกี่ยวกับการพัฒนา Android
- Android Studio (ดาวน์โหลดได้ที่นี่หากยังไม่มี)
- โปรแกรมจำลองหรืออุปกรณ์ Android (ใช้งานได้ผ่าน Android Studio)
- โค้ดตัวอย่าง (ดูขั้นตอนถัดไป)
คุณจะให้คะแนนประสบการณ์ในการสร้างแอป Android ของคุณในระดับใด
2. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์
ต้องดำเนินการต่อจาก MDC-103 ใช่ไหม
หากคุณดำเนินการ MDC-103 เสร็จสมบูรณ์แล้ว โค้ดของคุณก็จะพร้อมใช้งานสำหรับ Codelab นี้ ข้ามไปยังขั้นตอนที่ 3
ต้องเริ่มใหม่ตั้งแต่ต้นใช่ไหม
ดาวน์โหลดแอป Codelab เริ่มต้น
แอปเริ่มต้นอยู่ในไดเรกทอรี material-components-android-codelabs-104-starter/java
อย่าลืม cd
ในไดเรกทอรีดังกล่าวก่อนเริ่มต้น
...หรือโคลนโมเดลจาก GitHub
หากต้องการโคลน Codelab นี้จาก GitHub ให้เรียกใช้คำสั่งต่อไปนี้
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 104-starter
โหลดโค้ดเริ่มต้นใน Android Studio
- เมื่อวิซาร์ดการตั้งค่าดำเนินการเสร็จแล้วและหน้าต่างยินดีต้อนรับสู่ Android Studio ปรากฏขึ้น ให้คลิกเปิดโปรเจ็กต์ Android Studio ที่มีอยู่ ไปที่ไดเรกทอรีที่คุณได้ติดตั้งโค้ดตัวอย่างไว้แล้ว และเลือก java -> ศาลเจ้า (หรือค้นหา shrine ในคอมพิวเตอร์) เพื่อเปิดโครงการ Shrine
- รอสักครู่เพื่อให้ Android Studio สร้างและซิงค์โปรเจ็กต์ ดังที่แสดงโดยสัญญาณบอกสถานะกิจกรรมที่ด้านล่างของหน้าต่าง Android Studio
- ณ จุดนี้ Android Studio อาจแสดงข้อผิดพลาดบางอย่างในเวอร์ชันเนื่องจากคุณไม่มี Android SDK หรือเครื่องมือสร้างบิลด์ ดังตัวอย่างด้านล่าง ทำตามวิธีการใน Android Studio เพื่อติดตั้ง/อัปเดตโปรเจ็กต์เหล่านี้ และซิงค์โปรเจ็กต์
เพิ่มทรัพยากร Dependency ของโปรเจ็กต์
โปรเจ็กต์ต้องขึ้นอยู่กับไลบรารีการสนับสนุนของ AndroidC สำหรับ Android โค้ดตัวอย่างที่คุณดาวน์โหลดควรมีการระบุทรัพยากร Dependency นี้อยู่แล้ว แต่ขอแนะนำให้ทำตามขั้นตอนต่อไปนี้เพื่อให้มั่นใจว่าโค้ดดังกล่าว
- ไปยังไฟล์
build.gradle
ของโมดูลapp
และตรวจสอบว่าการบล็อก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 ทำงานอยู่ในอุปกรณ์ของคุณ
3. เพิ่มเมนูฉากหลัง
ฉากหลังเป็นพื้นผิวด้านหลังที่ไกลที่สุดของแอป โดยจะปรากฏอยู่หลังเนื้อหาและคอมโพเนนต์อื่นๆ ทั้งหมด ซึ่งประกอบด้วย 2 พื้นผิว ได้แก่ เลเยอร์หลัง (ซึ่งแสดงการทำงานและตัวกรอง) และเลเยอร์หน้า (ซึ่งแสดงเนื้อหา) คุณสามารถใช้ฉากหลังเพื่อแสดงข้อมูลและการดำเนินการแบบอินเทอร์แอกทีฟ เช่น การนำทางหรือตัวกรองเนื้อหา
ปกปิดเนื้อหาในตารางกริด
ใน shr_product_grid_fragment.xml
ให้เพิ่มแอตทริบิวต์ android:visibility="gone"
ลงใน NestedScrollView
เพื่อนำเนื้อหาผลิตภัณฑ์ออกชั่วคราว
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:elevation="8dp"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
เราจะติดตั้งฉากหลังในภูมิภาคนี้ เราจะทำให้ฉากหลังมีสีเดียวกับแถบแอปด้านบนเพื่อหลีกเลี่ยงการแสดงส่วนระหว่างแถบแอปด้านบนกับเนื้อหาเมนูที่ปรากฏบนฉากหลัง
ใน shr_product_grid_fragment.xml
ให้เพิ่มรายการต่อไปนี้เป็นองค์ประกอบแรกในราก FrameLayout
ก่อน AppBarLayout
shr_product_grid_fragment.xml
<LinearLayout
style="@style/Widget.Shrine.Backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="100dp"
android:paddingBottom="100dp">
</LinearLayout>
ใน styles.xml
ให้เพิ่มข้อมูลต่อไปนี้
styles.xml
<style name="Widget.Shrine.Backdrop" parent="">
<item name="android:background">?attr/colorAccent</item>
</style>
เยี่ยมมาก! คุณได้เพิ่มฉากหลังที่สวยงามลงใน UI ของศาลเจ้าแล้ว ต่อไป เราจะเพิ่มเมนู
เพิ่มเมนู
เมนูก็คือรายการปุ่มข้อความ เดี๋ยวเราจะเพิ่มให้ที่นี่
สร้างเลย์เอาต์ใหม่ชื่อ shr_backdrop.xml
ในไดเรกทอรี res -> layout
และเพิ่มสิ่งต่อไปนี้
shr_backdrop.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_featured_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_apartment_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_accessories_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_shoes_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_tops_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_bottoms_label" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_dresses_label" />
<View
android:layout_width="56dp"
android:layout_height="1dp"
android:layout_margin="16dp"
android:background="?android:attr/textColorPrimary" />
<com.google.android.material.button.MaterialButton
style="@style/Widget.Shrine.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shr_account_label" />
</merge>
และเพิ่มรายการนี้ใน LinearLayout
ที่คุณเพิ่งเพิ่มใน shr_product_grid_fragment.xml
โดยใช้แท็ก <include>
:
shr_product_grid_fragment.xml
<LinearLayout
style="@style/Widget.Shrine.Backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="88dp">
<include layout="@layout/shr_backdrop" />
</LinearLayout>
สร้างและเรียกใช้ หน้าจอหลักควรมีลักษณะดังนี้
ฉากหลังของคุณเสร็จแล้ว เรามาลบเนื้อหาที่เราปกปิดไว้ก่อนหน้านี้กัน
4. เพิ่มรูปร่าง
ก่อนที่เราจะทำการเปลี่ยนแปลงใดๆ กับ Shrine ใน Codelab นี้ เนื้อหาหลักของผลิตภัณฑ์นั้นอยู่ที่ส่วนหลังสุด เมื่อเพิ่มฉากหลัง เนื้อหานี้จะได้รับการเน้นให้เด่นชัดมากขึ้นเนื่องจากไปปรากฏอยู่ด้านหน้าฉากหลังนั้น
เพิ่มเลเยอร์ใหม่
เราควรแสดงเลเยอร์ตารางกริดผลิตภัณฑ์อีกครั้ง นำแอตทริบิวต์ android:visibility="gone"
ออกจาก NestedScrollView
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:elevation="8dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
มาจัดรูปแบบของเลเยอร์หน้าด้วยรอยบากที่มุมบนซ้ายกัน ดีไซน์ Material หมายถึงการปรับแต่งประเภทนี้ในรูปแบบรูปร่าง พื้นผิวของวัสดุสามารถแสดงในรูปทรงต่างๆ รูปทรงช่วยเพิ่มความโดดเด่นและสไตล์ให้กับพื้นผิวต่างๆ และใช้เพื่อแสดงการสร้างแบรนด์ได้ รูปร่างของวัสดุอาจมีมุมและขอบโค้งหรือมุม และมีด้านเท่าใดก็ได้ อาจเป็นแบบสมมาตรหรือไม่สม่ำเสมอ
เพิ่มรูปร่าง
แก้ไขรูปร่างของตารางกริด เราจัดเตรียมพื้นหลังรูปร่างที่กำหนดเองไว้ให้แล้ว แต่รูปร่างจะแสดงอย่างถูกต้องบน Android Marshmallow ขึ้นไปเท่านั้น เราตั้งค่าพื้นหลัง shr_product_grid_background_shape
ใน NestedScrollView
ได้เฉพาะใน Android Marshmallow ขึ้นไป ก่อนอื่นให้เพิ่ม id
ไปยัง NestedScrollView
เพื่อให้เราอ้างอิงในโค้ดได้ ดังนี้
shr_product_grid_fragment.xml
<androidx.core.widget.NestedScrollView
android:id="@+id/product_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:elevation="8dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
จากนั้นตั้งค่าพื้นหลังแบบเป็นโปรแกรมใน ProductGridFragment.java
เพิ่มตรรกะต่อไปนี้เพื่อกำหนดพื้นหลังเป็นส่วนท้ายของ onCreateView()
ก่อนคำสั่งการคืนสินค้า
ProductGridFragment.java
// Set cut corner background for API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
view.findViewById(R.id.product_grid).setBackgroundResource(R.drawable.shr_product_grid_background_shape);
}
สุดท้าย เราจะอัปเดตทรัพยากรสี productGridBackgroundColor
(ซึ่งใช้สำหรับพื้นหลังรูปร่างที่กำหนดเองเช่นกัน) ดังต่อไปนี้
colors.xml
<color name="productGridBackgroundColor">#FFFBFA</color>
สร้างและเรียกใช้
เราจึงเพิ่มรูปร่างแบบกำหนดเองนี้เข้ากับพื้นผิวหลักของศาลเจ้า เนื่องจากระดับความสูงของพื้นผิว ผู้ใช้จะเห็นว่ามีบางอย่างอยู่ด้านหลังเลเยอร์สีขาวด้านหน้า ลองเพิ่มภาพเคลื่อนไหวเพื่อให้ผู้ใช้เห็นว่ามีเมนูอะไรบ้าง
5. เพิ่มการเคลื่อนไหว
ภาพเคลื่อนไหวคือวิธีที่ทำให้แอปมีชีวิตชีวา ภาพเคลื่อนไหวอาจยิ่งใหญ่และเร้าใจ บอบบางและเล็กน้อย หรืออยู่ตรงกลางระหว่างนั้น ประเภทการเคลื่อนไหวที่คุณใช้ควรเหมาะสมกับสถานการณ์ การเคลื่อนไหวที่ใช้กับการกระทำปกติซ้ำๆ ควรมีขนาดเล็กและบอบบาง เพื่อไม่ให้ใช้เวลามากเกินไปเป็นประจำ ในสถานการณ์อื่นๆ เช่น ครั้งแรกที่ผู้ใช้เปิดแอป อาจสะดุดตามากกว่า และให้ข้อมูลเกี่ยวกับวิธีใช้แอปแก่ผู้ใช้
เพิ่มการเคลื่อนไหว "แสดง" ลงในปุ่มเมนู
การเคลื่อนไหวคือรูปร่างด้านหน้าที่เคลื่อนลงมาด้านล่าง เราได้จัดเตรียม Listener การคลิกให้คุณแล้ว ซึ่งจะทำภาพเคลื่อนไหวการแปลสำหรับชีตให้เสร็จสิ้นใน NavigationIconClickListener.java
เราสามารถตั้งค่า Listener การคลิกนี้ภายในเมธอด setupToolbar()
ของ ProductGridFragment.java
:
ProductGridFragment.java
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
ตอนนี้เมธอด setUpToolbar()
ของคุณควรมีลักษณะดังนี้
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);
}
toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
}
สร้างและเรียกใช้ กดปุ่มเมนู:
การกดไอคอนเมนูการนำทางอีกครั้งจะเป็นการซ่อนเมนูดังกล่าว
ปรับแต่งการเคลื่อนไหวของเลเยอร์หน้า
การเคลื่อนไหวเป็นวิธีที่ยอดเยี่ยมในการแสดงแบรนด์ มาดูกันว่าภาพเคลื่อนไหวแสดงเป็นอย่างไรโดยใช้เส้นโค้งเวลาที่แตกต่างกัน
อัปเดตโค้ดใน setupToolbar()
ใน ProductGridFragment.java
เพื่อส่งผ่าน Interpolator ไปยัง Listener การคลิกของไอคอนการนำทาง ดังนี้
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); } toolbar.setNavigationOnClickListener(new NavigationIconClickListener( getContext(), view.findViewById(R.id.product_grid), new AccelerateDecelerateInterpolator())); }
วิธีนี้จะทำให้เกิดผลกระทบที่แตกต่างกันใช่หรือไม่
6. ไอคอนแบรนด์
ระบบการตีความสัญลักษณ์ของแบรนด์ยังครอบคลุมถึงไอคอนที่คุ้นเคยด้วยเช่นกัน เราจะทำให้ไอคอนแสดงขึ้นมาเป็นแบบกำหนดเองและรวมเข้ากับชื่อของเราเพื่อให้ภาพลักษณ์ของแบรนด์ไม่ซ้ำใคร
เปลี่ยนไอคอนปุ่มเมนู
เปลี่ยนปุ่มเมนูให้แสดงไอคอนที่มีการออกแบบรูปข้าวหลามตัด อัปเดตแถบเครื่องมือใน shr_product_grid_fragment.xml
เพื่อใช้ไอคอนแบรนด์ใหม่ที่เรามีให้ (shr_branded_menu
) และตั้งค่าแอตทริบิวต์ app:contentInsetStart
และ android:padding
เพื่อทำให้แถบเครื่องมือตรงกับข้อกำหนดของนักออกแบบมากขึ้น
shr_product_grid_fragment.xml
<androidx.appcompat.widget.Toolbar android:id="@+id/app_bar" style="@style/Widget.Shrine.Toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:paddingStart="12dp" android:paddingLeft="12dp" android:paddingEnd="12dp" android:paddingRight="12dp" app:contentInsetStart="0dp" app:navigationIcon="@drawable/shr_branded_menu" app:title="@string/shr_app_name" />
อัปเดต Listener การคลิกอีกครั้งใน setupToolbar()
ใน ProductGridFragment.java
เพื่อนำคำสั่งที่ถอนออกได้ของแถบเครื่องมือเมื่อเมนูเปิดอยู่และเมื่อปิด ดังนี้
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); } toolbar.setNavigationOnClickListener(new NavigationIconClickListener( getContext(), view.findViewById(R.id.product_grid), new AccelerateDecelerateInterpolator(), getContext().getResources().getDrawable(R.drawable.shr_branded_menu), // Menu open icon getContext().getResources().getDrawable(R.drawable.shr_close_menu))); // Menu close icon }
สร้างและเรียกใช้
เยี่ยมไปเลย เมื่อเผยฉากหลังได้ ไอคอนเมนูสี่เหลี่ยมข้าวหลามตัดจะปรากฏขึ้น หากเมนูสามารถปิดบังได้ ไอคอนปิดจะแสดงขึ้นแทน
7. สรุป
จาก Codelab ทั้ง 4 ครั้งนี้ คุณได้เห็นวิธีใช้ Material Components ในการสร้างประสบการณ์การใช้งานที่สง่างามไม่เหมือนใคร ซึ่งสะท้อนถึงบุคลิกและสไตล์ของแบรนด์
ขั้นตอนถัดไป
Codelab ที่ชื่อว่า MDC-104 นี้ทำให้ลำดับ Codelab นี้เสร็จสมบูรณ์ คุณสามารถดูคอมโพเนนต์เพิ่มเติมใน MDC-Android ได้โดยไปที่แคตตาล็อกวิดเจ็ตของ Android
หากพบปัญหากับ Codelab นี้อีก ให้แก้ไขแอปพลิเคชัน Shrine เพื่อเปลี่ยนรูปภาพผลิตภัณฑ์ที่แสดงเมื่อมีการเลือกหมวดหมู่จากเมนูฉากหลัง
หากต้องการดูวิธีเชื่อมต่อแอปนี้กับ Firebase เพื่อแบ็กเอนด์ที่ใช้งานได้ โปรดดู Firebase Android Codelab