MDC-102 na Androida: struktura i układ materiału (Java)

Logo_components_color_2x_web_96dp.png

Komponenty Material Design (MDC) pomagają deweloperom wdrażać Material Design. Firma MDC została stworzona przez zespół inżynierów i projektantów UX w Google. Zawiera ona dziesiątki pięknych i funkcjonalnych elementów interfejsu oraz jest dostępna w aplikacjach na Androida, iOS, internet oraz Flutter.

material.io/develop

W laboratorium MDC-101 do utworzenia strony logowania zostały użyte 2 komponenty Material Design (MDC): pola tekstowe i przyciski. Teraz opanujemy tę podstawę poprzez dodanie elementów nawigacyjnych, struktury i danych.

Co stworzysz

W tym ćwiczeniu utworzysz ekran główny aplikacji o nazwie Shrine – sklepu internetowego, który sprzedaje ubrania i wyposażenie domu. Tabela zawiera:

  • Górny pasek aplikacji
  • Lista produktów w formie siatki

Komponenty MDC-Android w tym kursie

  • Układ AppBar
  • Widok kart

Czego potrzebujesz

  • Podstawowa wiedza na temat programowania Androida
  • Android Studio (pobierz go tutaj, jeśli jeszcze go nie masz)
  • Emulator lub urządzenie z Androidem (dostępne w Android Studio)
  • Przykładowy kod (patrz następny krok)

Jak oceniasz tworzenie aplikacji na Androida?

Początkujący Średnio zaawansowany Zaawansowany

Kontynuujesz z MDC-101?

Jeśli ukończyłeś MDC-101, Twój kod powinien być gotowy do tego ćwiczenia. Możesz to zrobić od razu do kroku 3: Dodawanie głównego paska aplikacji.

Zaczynasz od zera?

Pobierz aplikację początkujących z programowania

Pobierz aplikację startową

Aplikacja startowa znajduje się w katalogu material-components-android-codelabs-102-starter/java. Pamiętaj, aby przed wykonaniem czynności umieścić w cd katalog.

...lub skopiuj z GitHuba

Aby skopiować to ćwiczenia z programowania na GitHubie, uruchom następujące polecenia:

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

Wczytywanie kodu startowego w Android Studio

  1. Gdy kreator konfiguracji zakończy się i pojawi się okno Witamy w Android Studio, kliknij Otwórz istniejący projekt Android Studio. Przejdź do katalogu, w którym jest zainstalowany przykładowy kod, i wybierz java -> Temple (lub wyszukaj na komputerze hasło sanktuarium), aby otworzyć projekt Shrine.
  2. Zaczekaj, aż Android Studio skompiluje i zsynchronizuje projekt, na co wskazują wskaźniki aktywności na dole okna Android Studio.
  3. W tym momencie Android Studio może wyświetlić błędy kompilacji, ponieważ brakuje w nim pakietu Android SDK lub narzędzi do kompilacji (takich jak ten poniżej). Postępuj zgodnie z instrukcjami w Android Studio, aby zainstalować lub zaktualizować te projekty, a następnie zsynchronizować projekt.

Dodawanie zależności od projektu

Projekt potrzebuje zależności od biblioteki pomocy MDC na Androida. Pobrany przykładowy kod powinien już być widoczny na liście, ale zalecamy wykonanie tych czynności, aby się upewnić.

  1. Przejdź do pliku build.gradle modułu app i upewnij się, że blok dependencies zawiera zależność w MDC na Androida:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (Opcjonalnie) W razie potrzeby zmodyfikuj plik build.gradle, dodając te zależności i zsynchronizuj projekt.
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'
}

Uruchamianie aplikacji startowej

  1. Sprawdź, czy konfiguracja kompilacji po lewej stronie przycisku Uruchom/Odtwórz ma wartość app.
  2. Naciśnij zielony przycisk Uruchom/Odtwórz, aby utworzyć i uruchomić aplikację.
  3. Jeśli w oknie Select Deployment Target (Wybierz cel wdrożenia) masz już dostępne urządzenie z Androidem, przejdź do kroku 8. W przeciwnym razie kliknij Utwórz nowe urządzenie wirtualne.
  4. Na ekranie Wybierz sprzęt wybierz telefon, na przykład Pixel 2, i kliknij Dalej.
  5. Na ekranie Obraz systemu wybierz najnowszą wersję Androida, najlepiej na najwyższym poziomie interfejsu API. Jeśli nie jest zainstalowany, kliknij widoczny link Pobierz, aby go pobrać.
  6. Kliknij Dalej.
  7. Na ekranie Wirtualne urządzenie z Androidem (AVD) pozostaw ustawienia bez zmian i kliknij Zakończ.
  8. W oknie celu wdrożenia wybierz urządzenie z Androidem.
  9. Kliknij OK.
  10. Android Studio skompiluje aplikację, wdroży ją i automatycznie otworzy na urządzeniu docelowym.

Gotowe. Powinna wyświetlić się strona logowania się do świątyni z ćwiczenia z programowania MDC-101.

Teraz, gdy ekran logowania wygląda dobrze, możemy uzupełnić aplikację o kilka produktów.

Ekran główny jest widoczny po zamknięciu strony logowania i wyświetla się ekran z informacją „Gotowe”. Wspaniale. Teraz jednak użytkownik nie musi podejmować żadnych działań ani nie wie, gdzie się znajduje. Aby Ci w tym pomóc, dodaj nawigację.

Material Design udostępnia wzorce nawigacji, które zapewniają wysoki poziom użyteczności. Jednym z najważniejszych komponentów nawigacyjnych jest pasek aplikacji.

Aby zapewnić użytkownikom nawigację i zapewnić im szybki dostęp do innych działań, dodaj do paska aplikacji najpopularniejszy interfejs.

Dodawanie widżetu AppBar

W shr_product_grid_fragment.xml usuń tag <LinearLayout> zawierający &"Udało Ci się!" TextView i zastąp go tym:

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>

Dane shr_product_grid_fragment.xml powinny wyglądać tak:

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>

Wiele pasków aplikacji ma przycisk obok tytułu. Dodajmy ikonę menu do naszej.

Dodawanie ikony nawigacji

Jeszcze w shr_product_grid_fragment.xml dodaj do komponentu XML Toolbar (który właśnie został dodany do układu):

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

Dane shr_product_grid_fragment.xml powinny wyglądać tak:

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>

Dodawanie przycisków czynności i stylowanie górnego paska aplikacji

Możesz też dodać przyciski na końcu paska aplikacji. W Androidzie są to przyciski czynności.

Styl głównego paska aplikacji i przycisków działania dodamy do jego menu w sposób zautomatyzowany.

Najpierw utwórz metodę konfiguracji paska narzędzi. Metoda powinna uzyskać odwołanie do paska narzędzi za pomocą id, a także do działania za pomocą getActivity(). Jeśli aktywność nie ma wartości null, ustaw Toolbar jako ActionBar, używając parametru 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);
   }
}

Następnie, tuż pod dodaną przed chwilą metodą setUpToolbar, zastąpimy właściwość onCreateOptionsMenu, by zapełnić zawartość shr_toolbar_menu.xml na pasku narzędzi:

ProductGridFragment.java

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
   super.onCreateOptionsMenu(menu, menuInflater);
}

Teraz dodaj wywołanie metody setUpToolbar, którą dodaliśmy do treści metody onCreateView(), z następującą treścią:

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

Na koniec dodaj metodę onCreate() do ProductGridFragment.java. W treści metody ustaw parametr setHasOptionMenu jako true.

Metoda powinna wyglądać tak:

ProductGridFragment.java

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setHasOptionsMenu(true);
}

Powyższy kod ustawia pasek aplikacji z naszego układu XML jako pasek działań dla tej aktywności. Wywołanie zwrotne onCreateOptionsMenu wskazuje, czego ma używać menu. W takim przypadku pozycja menu z menu R.menu.shr_toolbar_menu zostanie umieszczona na pasku aplikacji.

Plik menu zawiera 2 elementy: "Szukaj" &"Filtr&quot.

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>

Po wprowadzeniu zmian plik ProductGridFragment.java powinien wyglądać tak:

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

}

Twórz i uruchamiaj. Twój ekran główny powinien wyglądać tak:

Teraz po prawej stronie znajduje się ikona nawigacji, tytuł i dwie ikony działań. Pasek narzędzi wyświetla również wysokość nad poziomem subtelnym, co oznacza, że jest on umieszczony w innej warstwie niż treść.

Teraz, gdy aplikacja ma już określoną strukturę, podziel ją na elementy na kartach.

Dodawanie karty

Zacznij od dodania jednej karty pod górnym paskiem aplikacji. Karta powinna zawierać region dla obrazu, tytułu i etykiety dla dodatkowego tekstu.

W elemencie shr_product_grid_fragment.xml dodaj następujące elementy (AppBarLayout) poniżej:

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>

Utwórz i uruchom:

Na tym podglądzie widać, że karta jest odsunięta od lewej krawędzi ekranu. Ma zaokrąglone rogi i cień (który reprezentuje wysokość karty). Cały obszar nazywa się &"container." Oprócz samego kontenera wszystkie jego elementy są opcjonalne.

Do kontenera możesz dodać te elementy: tekst nagłówka, miniaturę lub awatara, tekst podtytułu, separatory, a nawet przyciski i ikony. Utworzona przed chwilą karta zawiera np. dwa TextView (1 w tytule i 1 w przypadku tekstu dodatkowego) w polu LinearLayout, u dołu karty.

Karty są zwykle wyświetlane w kolekcji w połączeniu z innymi kartami. W następnej części tego ćwiczenia omówimy układ ich w formie siatki w siatce.

Jeśli na ekranie znajduje się wiele kart, są one grupowane w co najmniej jedną kolekcję. Karty w siatce mają układ współrzędny, co oznacza, że mają taką samą wysokość spoczynkową (chyba że zostały odebrane lub przeciągnięte, ale o tym nie dowiesz się w tym ćwiczeniu z programowania).

Konfigurowanie siatki kart

Przejrzyj plik shr_product_card.xml, który dla Ciebie przygotowaliśmy:

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>

Ten układ karty zawiera kartę z obrazem (tutaj: NetworkImageView, która umożliwia dodawanie obrazów z adresu URL) oraz 2 TextViews.

Teraz spójrz na przedstawione przez nas ProductCardRecyclerViewAdapter. Zawiera ten sam pakiet co 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();
   }
}

Klasa karty powyżej służy do zarządzania treścią siatki. Aby określić, co ma się stać z poszczególnymi wyświetleniami treści, wkrótce napiszemy kod dla: onBindViewHolder().

W tym samym pakiecie znajdziesz także ProductCardViewHolder. Te zajęcia zawierają widoki wpływające na układ karty, więc możemy je później zmodyfikować.

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

Aby skonfigurować siatkę, najpierw usuń symbol zastępczy MaterialCardView z elementu shr_product_grid_fragment.xml. Następnie dodaj komponent reprezentujący naszą siatkę kart. W takim przypadku dodaj komponent RecyclerView do elementu shr_product_grid_fragment.xml pod komponentem 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>

Dane shr_product_grid_fragment.xml powinny wyglądać tak:

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>

Na koniec w polu onCreateView() dodaj kod inicjacji RecyclerView do elementu ProductGridFragment.java po wywołaniu metody setUpToolbar(view) i przed instrukcją 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;
}

Powyższy fragment kodu zawiera kroki wymagane do skonfigurowania RecyclerView. To obejmuje ustawienie Menedżera układu RecyclerView oraz zainicjowanie i skonfigurowanie adaptera RecyclerView&#39.

Twój plik ProductGridFragment.java powinien teraz wyglądać tak:

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

}

Twórz i uruchamiaj.

Karty są już dostępne! Nie wyświetlają jeszcze niczego, więc dodajmy dane produktów.

Dodawanie obrazów i tekstów

Do każdej karty dodaj zdjęcie, nazwę produktu i cenę. Abstrakcja ViewHolder zawiera obejrzenia każdej karty. W ViewHolder dodaj 3 widoki w ten sposób:

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

W narzędziu RecyclerView i ViewHolder, zaktualizuj metodę onBindViewHolder(), by ustawić informacje o każdym widoku:

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

Powyższy kod informuje nasz adapter RecyclerView&#39', co zrobić z każdą kartą, używając ViewHolder.

Tutaj ustawia dane tekstowe dla każdego elementu ViewHolder w TextView i wywołuje ImageRequester, aby pobrać obraz z adresu URL. ImageRequester to klasa, którą udostępniamy dla Twojej wygody. Wykorzystuje ona bibliotekę Volley (to temat wykraczający poza zakres tych ćwiczeń z programowania, ale możesz samodzielnie przeanalizować kod).

Utwórz i uruchom:

Nasze produkty wyświetlają się już w aplikacji.

Nasza aplikacja ma interfejs podstawowy, który przenosi użytkownika z ekranu logowania na ekran główny, na którym można przeglądać produkty. W kilku wierszach kodu dodaliśmy górny pasek aplikacji z tytułem i 3 przyciskami oraz siatkę kart, która prezentuje zawartość aplikacji. Ekran główny jest prosty i funkcjonalny, ma podstawową strukturę i zawiera przydatne treści.

Dalsze kroki

Na górnym pasku aplikacji, karcie, w polu tekstowym i przycisku dodaliśmy 4 główne komponenty Material Design z biblioteki MDC-Android. Jeszcze więcej znajdziesz w komponentach MDC-Android Catalog.

Jest w pełni funkcjonalna, ale nasza aplikacja jeszcze nie wyraża konkretnej marki. W filmie MDC-103: Material Design Theming with Color, Shape, Elevation and Type będziemy dostosowywać styl tych komponentów, tak aby pasował do Twojej marki.

Ukończenie ćwiczeń z programowania było sporą ilością czasu i wysiłku.

Całkowicie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Całkowicie się nie zgadzam

Chcę w przyszłości nadal korzystać z Komponentów Material Design

Całkowicie się zgadzam Zgadzam się Nie mam zdania Nie zgadzam się Całkowicie się nie zgadzam