MDC-102 Android: Materyal Yapı ve Düzen (Kotlin)

1. Giriş

logo_components_color_2x_web_96dp.png

Materyal Bileşenleri (MDC), geliştiricilerin Materyal Tasarım'ı uygulamasına yardımcı olur. Google'da mühendislerden ve kullanıcı deneyimi tasarımcılarından oluşan bir ekip tarafından oluşturulan MDC, onlarca güzel ve işlevsel kullanıcı arayüzü bileşeni içerir. Ayrıca Android, iOS, web ve Flutter.material.io/develop'da kullanılabilir.

MDC-101 kod laboratuvarında, giriş sayfası oluşturmak için iki Material bileşeni (MDC) kullandınız: mürekkep dalgaları içeren metin alanları ve düğmeler. Şimdi gezinme, yapı ve veri ekleyerek bu temeli genişletelim.

Oluşturacağınız uygulama

Bu codelab'de, giyim ve ev eşyaları satan bir e-ticaret uygulaması olan Shrine için bir ana ekran oluşturacaksınız. Şunları içerecektir:

  • Üst uygulama çubuğu
  • Ürünlerle dolu bir tablo listesi

249db074eff043f4.png

Bu codelab'deki MDC-Android bileşenleri

  • AppBarLayout
  • MaterialCardView

Gerekenler

  • Android geliştirmeyle ilgili temel bilgiler
  • Android Studio (Yok ise buradan indirin)
  • Bir Android emülatörü veya cihaz (Android Studio üzerinden kullanılabilir)
  • Örnek kod (sonraki adıma bakın)

Android uygulamaları geliştirme konusundaki deneyim düzeyinizi nasıl değerlendirirsiniz?

Acemi Orta Seviye Uzman

2. Geliştirme ortamınızı ayarlama

MDC-101'den devam mı ediyorsunuz?

MDC-101 kursunu tamamladıysanız kodunuz bu codelab için hazırlanmış olmalıdır. 3. adıma (Üst uygulama çubuğu ekleme) atlayın.

Sıfırdan mı başlayacaksınız?

Başlangıç Codelab uygulamasını indirin

Başlangıç uygulaması material-components-android-codelabs-102-starter/kotlin dizininde bulunur. Başlamadan önce bu dizine cd eklediğinizden emin olun.

...veya GitHub'dan klonlayın

Bu kod laboratuvarını GitHub'dan kopyalamak için aşağıdaki komutları çalıştırın:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 102-starter

Android Studio'da başlangıç kodunu yükleme

  1. Kurulum sihirbazı tamamlandıktan ve Android Studio'ya hoş geldiniz penceresi gösterildikten sonra Mevcut bir Android Studio projesini aç'ı tıklayın. Örnek kodu yüklediğiniz dizine gidin ve Shipping projesini açmak için kotlin -> shrine'ı seçin (veya bilgisayarınızda shrine için arama yapın).
  2. Android Studio'nun projeyi oluşturup senkronize etmesi için biraz bekleyin. Bunu, Android Studio penceresinin alt kısmındaki etkinlik göstergelerinde de görebilirsiniz.
  3. Bu noktada Android Studio, Android SDK'sı veya aşağıda gösterilen gibi derleme araçları eksik olduğu için bazı derleme hataları oluşturabilir. Bunları yüklemek/güncellemek ve projenizi senkronize etmek için Android Studio'daki talimatları uygulayın.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

Proje bağımlılıklarını ekleme

Projenin MDC Android destek kitaplığına bağımlı olması gerekir. İndirdiğiniz örnek kodda bu bağımlılık zaten listelenecektir ancak emin olmak için aşağıdaki adımları uygulamanız önerilir.

  1. app modülünün build.gradle dosyasına gidin ve dependencies bloğunun MDC Android bağımlığı içerdiğinden emin olun:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (İsteğe bağlı) Gerekirse aşağıdaki bağımlılıkları eklemek ve projeyi senkronize etmek için build.gradle dosyasını düzenleyin.
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'
}

Başlatıcı uygulamayı çalıştırma

  1. Çalıştır / Oynat düğmesinin solundaki derleme yapılandırmasının app olduğundan emin olun.
  2. Uygulamayı derleyip çalıştırmak için yeşil Çalıştır/Oynat düğmesine basın.
  3. Select Deployment Target (Dağıtım Hedefi Seçin) penceresinde, kullanılabilir cihazlarınız arasında zaten bir Android cihazınız varsa, 8. Adım'a atlayın. Aksi takdirde, Yeni Sanal Cihaz Oluştur'u tıklayın.
  4. Donanım Seçin ekranında Pixel 2 gibi bir telefon cihazı seçin ve Sonraki'yi tıklayın.
  5. Sistem Görüntüsü ekranında, tercihen en yüksek API düzeyinde bir son Android sürümünü seçin. Yüklü değilse gösterilen İndir bağlantısını tıklayıp indirme işlemini tamamlayın.
  6. İleri'yi tıklayın.
  7. Android Virtual Device (AVD) ekranında ayarları olduğu gibi bırakıp Son'u tıklayın.
  8. Dağıtım hedefi iletişim kutusundan bir Android cihaz seçin.
  9. Ok'i (Tamam) tıklayın.
  10. Android Studio, uygulamayı oluşturur, dağıtır ve hedef cihazda otomatik olarak açar.

Başarıyla gerçekleştirildi. MDC-101 kod laboratuvarındaki Shrine giriş sayfasını görürsünüz.

4cb0c218948144b4.png

Giriş ekranı iyi göründüğüne göre uygulamayı bazı ürünlerle dolduralım.

3. Üst uygulama çubuğu ekle

Giriş sayfası kapatıldığında "Bunu başardınız" yazan bir ekranla birlikte ana ekran gösterilir. Harika! Ancak kullanıcımız şu anda herhangi bir işlem yapamıyor veya uygulamada nerede olduğunu bilmiyor. Bu konuda yardımcı olmak için gezinme menüsü ekleme zamanı geldi.

Materyal Tasarım, yüksek düzeyde kullanılabilirlik sağlayan gezinme kalıpları sunar. En görünür bileşenlerden biri üst uygulama çubuğudur.

Gezinme sağlamak ve kullanıcılara diğer işlemlere hızlı erişim sağlamak için üst uygulama çubuğu ekleyelim.

AppBar widget'ı ekleme

shr_product_grid_fragment.xml dosyasında, "Bunu başardınız!" ifadesini içeren <LinearLayout> bloğunu silin. TextView ve bunu aşağıdakiyle değiştirin:

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 artık şu şekilde görünmelidir:

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>

Birçok uygulama çubuğunun başlığının yanında bir düğme bulunur. Bizimkine bir menü simgesi ekleyelim.

Gezinme simgesi ekleme

shr_product_grid_fragment.xml hâlâ açıkken düzeninize eklediğiniz Toolbar XML bileşenine aşağıdakini ekleyin:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

shr_product_grid_fragment.xml şu şekilde görünmelidir:

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>

İşlem düğmeleri ekleme ve üst uygulama çubuğuna stil uygulama

Uygulama çubuğunun son tarafına da düğme ekleyebilirsiniz. Android'de bunlara işlem düğmeleri adı verilir. Üst uygulama çubuğunun stilini belirleyeceğiz ve menüsüne programatik olarak işlem düğmeleri ekleyeceğiz.

ProductGridFragment.kt işlevinin onCreateView işlevinde, activity öğesinin Toolbar değerini setSupportActionBar kullanarak ActionBar olarak kullanılacak şekilde ayarlayın. Bunu, görünüm oluşturulduktan sonra inflater ile yapabilirsiniz.

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

Ardından, araç çubuğunu ayarlamak için değiştirdiğimiz yöntemin hemen altında, shr_toolbar_menu.xml içeriğini araç çubuğuna eklemek için onCreateOptionsMenu'ü geçersiz kılalım:

ProductGridFragment.kt

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

Son olarak, ProductGridFragment.kt içinde onCreate() değerini geçersiz kılın ve super() çağrısından sonra, true ile setHasOptionMenu çağrısı yapın:

ProductGridFragment.kt

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

Yukarıdaki kod snippet'leri, XML düzenimizdeki uygulama çubuğunu bu etkinlik için İşlem Çubuğu olarak ayarlar. Geri çağırma onCreateOptionsMenu, etkinliğe hangi menünün kullanılacağını bildirir. Bu durumda, R.menu.shr_toolbar_menu'teki menü öğeleri uygulama çubuğuna yerleştirilir. Menü dosyası iki öğe içerir: "Ara" ve "Filtre".

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>

Bu değişikliklerden sonra ProductGridFragment.kt dosyanız aşağıdaki gibi görünmelidir:

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

Derleyin ve çalıştırın. Ana ekranınız aşağıdaki gibi görünecektir:

d04e8aa3b27f4754.png

Araç çubuğunda artık sağ tarafta bir gezinme simgesi, bir başlık ve iki işlem simgesi bulunuyor. Araç çubuğu, yüksekliği içerikten farklı bir katmanda olduğunu gösteren ince bir gölge kullanarak da gösterir.

4. Kart ekleyin

Uygulamamızın bir yapısı olduğuna göre içeriği kartlara yerleştirerek düzenleyelim.

Kart ekleme

Üst uygulama çubuğunun altına bir kart ekleyerek başlayalım. Kartta resim için bir bölge, başlık ve ikincil metin için bir etiket olmalıdır. Aşağıdakileri AppBarLayout altındaki shr_product_grid_fragment.xml bölümüne ekleyin.

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>

Derleme ve çalıştırma:

f6184a55ccb5f920.png

Bu önizlemede, kartın sol kenardan içeri doğru yerleştirildiğini, köşeleri yuvarlatılmış ve bir gölge (kartın yüksekliğini ifade eder) olduğunu görebilirsiniz. Öğenin tamamına "kapsayıcı" adı verilir. Kapsayıcı dışında, içerdiği tüm öğeler isteğe bağlıdır.

Bir kapsayıcıya şu öğeleri ekleyebilirsiniz: başlık metni, küçük resim veya avatar, alt başlık metni, ayırıcılar, hatta düğmeler ve simgeler. Örneğin, yeni oluşturduğumuz kartta, kartın alt kısmına hizalanmış bir LinearLayout içinde iki TextView (biri başlık, diğeri ikincil metin için) yer alır.

Kartlar genellikle diğer kartlarla birlikte bir koleksiyonda gösterilir. Bu codelab'in bir sonraki bölümünde, uygulamaları tablo içinde bir koleksiyon olarak düzenleyeceğiz.

5. Kart ızgarası oluşturma

Bir ekranda birden fazla kart varsa bunlar bir veya daha fazla koleksiyonda gruplandırılır. Izgara içindeki kartlar aynı düzlemde yer alır. Diğer bir deyişle, alınıp sürüklenmedikleri sürece, durmadıklarında aynı yükseklikleri paylaşırlar (ancak bu codelab'de bu konuya değinmeyeceğiz).

Kart ızgarasını ayarlama

Size sağladığımız shr_product_card.xml dosyasına göz atın:

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>

Bu kart düzeninde, resim içeren bir kart (bu durumda, bir URL'den resim yükleyip göstermemize olanak tanıyan bir NetworkImageView) ve iki TextViews yer alır.

Ardından, sizin için sağladığımız ProductCardRecyclerViewAdapter'e göz atın. ProductGridFragment ile aynı pakettedir.

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

Yukarıdaki bağdaştırıcı sınıfı, ızgaramızın içeriğini yönetir. Her bir görünümün, ilgili içerikle ne yapacağını belirlemek için yakında onBindViewHolder() kodunu yazacağız.

Aynı pakette ProductCardViewHolder dosyasına da göz atabilirsiniz. Bu sınıf, kart düzenimizi etkileyen görünümleri depolar. Böylece, bunları daha sonra değiştirebiliriz.

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)

Izgaramızı ayarlamak için önce shr_product_grid_fragment.xml öğesinden MaterialCardView yer tutucusunu kaldıracağız. Ardından, kart ızgaramızı temsil eden bileşeni eklemeniz gerekir. Bu örnekte RecyclerView kullanacağız. RecyclerView bileşenini, AppBarLayout XML bileşeninizin altındaki shr_product_grid_fragment.xml öğesine ekleyin:

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 dosyanız aşağıdaki gibi görünmelidir:

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>

Son olarak, onCreateView() içinde setUpToolbar(view) çağrısından sonra ve return ifadesi öncesinde RecyclerView ilk kullanıma hazırlama kodunu ProductGridFragment.kt içine ekleyin:

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

Yukarıdaki kod snippet'i, bir RecyclerView oluşturmak için gerekli başlatma adımlarını içerir. Bu işlem, RecyclerView cihazının düzen yöneticisinin ayarlanmasını, ayrıca RecyclerView bağdaştırıcısının başlatılmasını ve ayarlanmasını içerir.

ProductGridFragment.kt dosyanız artık aşağıdaki gibi görünecektir:

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

Derleme ve çalıştırma:

f9aeab846fc3bb4c.png

Kartlar elinize ulaştı. Bu ürünler henüz hiçbir şey göstermiyor. Bu nedenle birkaç ürün verisi ekleyelim.

Resim ve metin ekleme

Her kart için bir resim, ürün adı ve fiyat ekleyin. ViewHolder soyutlamamız her kartın görüntüleme sayısını içerir. ViewHolder dosyamıza üç görünümü aşağıdaki gibi ekleyin.

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

Her ürün görünümünün başlığını, fiyatını ve ürün resmini ayarlamak için ProductCardRecyclerViewAdapter içindeki onBindViewHolder() yöntemini aşağıda gösterildiği gibi güncelleyin:

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

Yukarıdaki kod, RecyclerView adaptörümüze ViewHolder kullanarak her kartla ne yapacağını söyler.

Burada, ViewHolder'nin TextView'lerinin her birinde metin verilerini ayarlar ve bir URL'den resim almak için ImageRequester çağırır. ImageRequester, size kolaylık sağlamak için sağladığımız bir sınıftır ve Volley kitaplığını kullanır (Bu, bu kod laboratuvarının kapsamı dışında bir konudur ancak kodu kendiniz keşfedebilirsiniz).

Aşağıdakileri derleyip çalıştırın:

249db074eff043f4.png

Ürünlerimiz artık uygulamada gösteriliyor.

6. Özet

Uygulamamızda, kullanıcıyı giriş ekranından ürünlerin görüntülenebileceği bir ana ekrana yönlendiren temel bir akış vardır. Birkaç satır kodla, bir başlık ve üç düğme içeren bir üst uygulama çubuğu ve uygulamamızın içeriğini sunmak için bir kart ızgarası ekledik. Artık basit ve işlevsel olan ana ekranımız, temel bir yapı ve üzerinde işlem yapılabilir içerik içeriyor.

Sonraki adımlar

Üst uygulama çubuğu, kart, metin alanı ve düğmeyle birlikte MDC-Android kitaplığındaki dört temel Material Design bileşenini de kullandık. MDC-Android Kataloğu'nu ziyaret ederek daha da fazla bileşeni keşfedebilirsiniz.

Tamamen işlevsel olsa da uygulamamız henüz belirli bir markayı veya tarzı ifade etmiyor. MDC-103: Renk, Şekil, Yükseklik ve Tür ile Materyal Tasarım Teması bölümünde canlı ve modern bir markayı ifade etmek için bu bileşenlerin stilini özelleştireceğiz.

Bu codelab'i makul bir zaman ve çabayla tamamlayabildim

Kesinlikle katılıyorum Katılıyorum Ne katılıyorum ne katılmıyorum Katılmıyorum Kesinlikle katılmıyorum

Gelecekte Material Components'i kullanmaya devam etmek istiyorum

Kesinlikle katılıyorum Katılıyorum Ne katılıyorum ne katılmıyorum Katılmıyorum Kesinlikle katılmıyorum