Android MDC-102: Tata Letak dan Struktur Material (Kotlin)

1. Pengantar

logo_components_color_2x_web_96dp.png

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

Dalam codelab MDC-101, Anda menggunakan dua Komponen Material (MDC) untuk membuat halaman login: tombol dan kolom teks dengan ripple tinta. Sekarang, mari kita perluas dasar ini dengan menambahkan navigasi, struktur, dan data.

Yang akan Anda buat

Dalam codelab ini, Anda akan mem-build layar utama untuk aplikasi bernama Shrine, sebuah aplikasi e-commerce yang menjual pakaian dan perlengkapan rumah. Layar utama ini akan berisi:

  • Panel aplikasi atas
  • Daftar petak yang lengkap berisi produk

249db074eff043f4.pngS

Komponen MDC-Android dalam codelab ini

  • AppBarLayout
  • MaterialCardView

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?

Pemula Menengah Mahir

2. Menyiapkan lingkungan pengembangan

Melanjutkan dari MDC-101?

Jika Anda sudah menyelesaikan MDC-101, kode Anda untuk codelab ini seharusnya sudah disiapkan. Langsung ke langkah 3: Tambahkan panel aplikasi atas.

Memulai dari awal?

Mendownload aplikasi codelab awal

Aplikasi awal terletak di direktori material-components-android-codelabs-102-starter/kotlin. Pastikan untuk memasukkan cd ke dalam direktori tersebut sebelum memulai.

...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 102-starter

Memuat kode awal di Android Studio

  1. 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 kotlin -> kuil (atau telusuri shrine di komputer Anda) untuk membuka proyek Pengiriman.
  2. Tunggu Android Studio mem-build dan menyinkronkan project, seperti yang ditunjukkan oleh indikator aktivitas di bagian bawah jendela Android Studio.
  3. 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.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

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.

  1. Buka file build.gradle modul app dan pastikan blok dependencies menyertakan dependensi pada Android MDC:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (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

  1. Pastikan konfigurasi build di sebelah kiri tombol Run / Play adalah app.
  2. Tekan tombol Run/Play berwarna hijau untuk mem-build dan menjalankan aplikasi.
  3. Di jendela Select Deployment Target, jika Anda sudah mencantumkan perangkat Android di perangkat yang tersedia, lanjutkan ke Langkah 8. Jika tidak tercantum, klik Create New Virtual Device.
  4. Di layar Select Hardware, pilih perangkat ponsel, misalnya Pixel 2, lalu klik Next.
  5. Di layar System Image, pilih recent Android version, terutama API level yang paling tinggi. Jika tidak terinstal, klik link Download yang ditampilkan dan selesaikan proses download-nya.
  6. Klik Next.
  7. Di layar Android Virtual Device (AVD), biarkan setelan apa adanya, lalu klik Finish.
  8. Pilih Android device dari dialog target deployment.
  9. Klik Ok.
  10. Android Studio mem-build, men-deploy, dan otomatis membuka aplikasi di perangkat target.

Berhasil! Anda akan melihat halaman login Shrine dari codelab MDC-101.

4cb0c218948144b4.pngS

Setelah layar login terlihat bagus, mari isi aplikasi dengan beberapa produk.

3. Menambahkan panel aplikasi atas

Layar utama ditampilkan saat halaman login ditutup, dengan layar yang bertuliskan "Anda berhasil!". Bagus! Namun, sekarang pengguna tidak dapat melakukan tindakan apa pun atau tidak tahu mereka di bagian aplikasi yang mana. Untuk membantu mengatasinya, kini saatnya Anda menambahkan navigasi.

Desain Material menawarkan pola navigasi yang memastikan tingkat kegunaan yang tinggi. Salah satu komponen yang paling terlihat adalah panel aplikasi atas.

Untuk menyediakan navigasi serta memberi pengguna akses cepat ke tindakan lainnya, mari tambahkan panel aplikasi atas.

Menambahkan widget AppBar

Di shr_product_grid_fragment.xml, hapus blok <LinearLayout> yang berisi pesan "Anda berhasil!" TextView dan ganti dengan kode berikut:

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 sekarang akan terlihat seperti berikut:

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>

Banyak panel aplikasi memiliki tombol di samping judul. Mari kita tambahkan ikon menu di milik kita.

Menambahkan ikon navigasi

Saat masih di shr_product_grid_fragment.xml, tambahkan kode berikut ke komponen XML Toolbar yang baru saja Anda tambahkan ke tata letak:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

shr_product_grid_fragment.xml Anda akan terlihat seperti berikut:

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>

Menambahkan tombol tindakan dan menata gaya panel aplikasi atas

Anda juga dapat menambahkan tombol ke sisi akhir panel aplikasi. Di Android, ini disebut tombol tindakan. Kita akan menata gaya panel aplikasi atas dan menambahkan tombol tindakan ke menunya secara terprogram.

Dalam fungsi onCreateView ProductGridFragment.kt, setel Toolbar activity untuk digunakan sebagai ActionBar menggunakan setSupportActionBar. Anda dapat melakukannya setelah tampilan dibuat dengan 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;
}

Selanjutnya, tepat di bawah metode yang baru saja kita ubah untuk menyiapkan toolbar, mari kita ganti onCreateOptionsMenu untuk meng-inflate konten shr_toolbar_menu.xml ke toolbar:

ProductGridFragment.kt

override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu)
   super.onCreateOptionsMenu(menu, menuInflater)
}

Terakhir, ganti onCreate() di ProductGridFragment.kt, dan setelah memanggil super(), panggil setHasOptionMenu dengan true:

ProductGridFragment.kt

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setHasOptionsMenu(true)
}

Cuplikan kode di atas menetapkan panel aplikasi dari tata letak XML menjadi Panel Tindakan untuk aktivitas ini. Callback onCreateOptionsMenu memberi tahu aktivitas apa yang akan digunakan sebagai menu. Dalam hal ini, tindakan ini akan menempatkan item menu dari R.menu.shr_toolbar_menu ke panel aplikasi. File menu berisi dua item: "Search" dan "Filter".

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>

Setelah perubahan tersebut, file ProductGridFragment.kt Anda akan terlihat seperti berikut:

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)
   }
}

Build dan jalankan. Layar utama Anda akan terlihat seperti ini:

d04e8aa3b27f4754.png

Sekarang toolbar memiliki ikon navigasi, judul, dan dua ikon tindakan di sisi kanan. {i>Toolbar<i} juga menampilkan elevasi menggunakan bayangan halus yang menunjukkannya di {i>layer<i} yang berbeda dengan konten.

4. Tambahkan kartu

Setelah aplikasi memiliki beberapa struktur, mari kita susun konten dengan menempatkannya di kartu.

Menambahkan kartu

Mari mulai dengan menambahkan satu kartu di bawah panel aplikasi atas. Kartu harus memiliki wilayah untuk gambar, judul, dan label untuk teks sekunder. Tambahkan hal berikut di shr_product_grid_fragment.xml di bawah 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>

Membangun dan menjalankan:

f6184a55ccb5f920.png

Dalam pratinjau ini, Anda dapat melihat kartu disisipkan dari tepi kiri, dan memiliki sudut membulat serta bayangan (yang menunjukkan ketinggian kartu). Seluruh elemen disebut "container". Selain container, semua elemen di dalamnya bersifat opsional.

Anda dapat menambahkan elemen-elemen berikut ke penampung: teks header, thumbnail atau avatar, teks subjudul, pemisah, dan bahkan tombol serta ikon. Kartu yang baru saja kita buat, misalnya, berisi dua TextView (satu untuk judul, dan satu untuk teks sekunder) dalam LinearLayout , yang diratakan dengan bagian bawah kartu.

Kartu biasanya ditampilkan dalam koleksi dengan kartu lain. Di bagian berikutnya dari codelab ini, kita akan menata letaknya sebagai koleksi dalam petak.

5. Membuat {i>grid of cards<i}

Jika ada beberapa kartu di layar, kartu tersebut akan dikelompokkan ke dalam satu atau beberapa koleksi. Kartu dalam petak bersifat sebidang, yang berarti kartu tersebut memiliki ketinggian istirahat yang sama satu sama lain (kecuali jika diambil atau ditarik, tetapi kita tidak akan membahasnya dalam codelab ini).

Menyiapkan petak kartu

Lihat file shr_product_card.xml yang telah kami berikan untuk Anda:

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>

Tata letak kartu ini berisi kartu dengan gambar (dalam hal ini, NetworkImageView, yang memungkinkan kita memuat dan menampilkan gambar dari URL), dan dua TextViews.

Selanjutnya, lihat ProductCardRecyclerViewAdapter yang kami berikan untuk Anda. ID ini berada dalam paket yang sama dengan 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
   }
}

Class adaptor di atas mengelola konten grid. Untuk menentukan apa yang harus dilakukan setiap tampilan dengan konten yang diberikan, kita akan segera menulis kode untuk onBindViewHolder().

Dalam paket yang sama, Anda juga dapat melihat ProductCardViewHolder. Class ini menyimpan tampilan yang memengaruhi tata letak kartu, sehingga kita dapat mengubahnya nanti.

ProductCardViewHolder.kt

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)

Untuk menyiapkan petak, pertama-tama kita perlu menghapus placeholder MaterialCardView dari shr_product_grid_fragment.xml. Selanjutnya, Anda harus menambahkan komponen yang mewakili {i>grid of cards<i} kita. Dalam hal ini, kita akan menggunakan RecyclerView. Tambahkan komponen RecyclerView ke shr_product_grid_fragment.xml di bawah komponen XML AppBarLayout Anda:

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 Anda akan terlihat seperti berikut:

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>

Terakhir, di onCreateView(), tambahkan kode inisialisasi RecyclerView ke dalam ProductGridFragment.kt setelah Anda memanggil setUpToolbar(view) dan sebelum pernyataan 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;
}

Cuplikan kode di atas berisi langkah-langkah inisialisasi yang diperlukan untuk menyiapkan RecyclerView. Hal ini termasuk menyetel pengelola tata letak RecyclerView, serta melakukan inisialisasi dan menyetel adaptor RecyclerView.

File ProductGridFragment.kt Anda sekarang akan terlihat seperti berikut:

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)
   }
}

Bangun dan jalankan:

f9aeab846fc3bb4c.png

Kartu-kartu itu sudah ada sekarang! Item tersebut belum menampilkan apa pun, jadi mari tambahkan beberapa data produk.

Menambahkan gambar dan teks

Untuk setiap kartu, tambahkan gambar, nama produk, dan harga. Abstraksi ViewHolder menyimpan tampilan untuk setiap kartu. Di ViewHolder, tambahkan tiga tampilan seperti berikut.

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)
}

Perbarui metode onBindViewHolder() di ProductCardRecyclerViewAdapter untuk menetapkan judul, harga, dan gambar produk untuk setiap tampilan produk seperti yang ditunjukkan di bawah ini:

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)
   }
}

Kode di atas memberi tahu adaptor RecyclerView apa yang harus dilakukan dengan setiap kartu, menggunakan ViewHolder.

Di sini, class ini menetapkan data teks di setiap TextView ViewHolder, dan memanggil ImageRequester untuk mendapatkan gambar dari URL. ImageRequester adalah class yang disediakan untuk memudahkan Anda, dan menggunakan library Volley (Ini adalah topik di luar cakupan codelab ini, tetapi Anda dapat mempelajari kodenya sendiri).

Bangun dan jalankan:

249db074eff043f4.pngS

Produk kami kini ditampilkan di aplikasi.

6. Rekap

Aplikasi ini memiliki alur dasar yang mengarahkan pengguna dari layar login ke layar utama, tempat produk dapat dilihat. Hanya dengan beberapa baris kode, kami menambahkan panel aplikasi atas dengan judul dan tiga tombol, serta petak kartu untuk menyajikan konten aplikasi. Layar utamanya kini sederhana dan fungsional, dengan struktur dasar dan konten yang dapat ditindaklanjuti.

Langkah berikutnya

Dengan panel aplikasi, kartu, kolom teks, dan tombol atas, kini kami telah menggunakan empat komponen Desain Material inti dari library MDC-Android. Anda dapat mempelajari lebih banyak komponen dengan membuka Katalog MDC-Android.

Meskipun berfungsi penuh, aplikasi kita belum mengekspresikan merek atau gaya tertentu. Dalam MDC-103: Memberi Tema Desain Material dengan Warna, Bentuk, Ketinggian, dan Jenis, kita akan menyesuaikan gaya komponen ini untuk mengekspresikan merek modern yang cerah.

Saya dapat menyelesaikan codelab ini dengan upaya dan dalam durasi waktu yang wajar

Sangat setuju Setuju Netral Tidak setuju Sangat tidak setuju

Saya ingin terus menggunakan Komponen Material pada masa mendatang

Sangat setuju Setuju Netral Tidak setuju Sangat tidak setuju