1. Wprowadzenie
Material Komponenty (MDC) pomagają deweloperom wdrażać interfejs Material Design. MDC, stworzona przez zespół inżynierów i projektantów UX w Google, zawiera dziesiątki pięknych i funkcjonalnych komponentów interfejsu. Jest dostępny na Androida, iOS, internet oraz Flutter.material.io/develop |
W ramach ćwiczenia w Codelabs w wersji MDC-101 do stworzenia strony logowania: pól tekstowych i przycisków wykorzystano 2 komponenty Material Komponenty (MDC). Rozwińmy te podstawy, dodając nawigację, strukturę i dane.
Co utworzysz
W ramach tego ćwiczenia w Codelabs utworzysz ekran główny aplikacji o nazwie Shrine, która umożliwia sprzedaż odzieży i artykułów wyposażenia domu. Będą one zawierać:
- Górny pasek aplikacji
- Siatka listy produktów
MDC-Android MDC-Android
- AppBarLayout
- MaterialCardView
Czego potrzebujesz
- Podstawowa wiedza o programowaniu aplikacji na Androida
- Android Studio (pobierz tę aplikację stąd, jeśli jeszcze jej nie masz)
- Emulator Androida lub urządzenie (dostępne w Android Studio).
- Przykładowy kod (patrz następny krok)
Jak oceniasz swój poziom doświadczenia w tworzeniu aplikacji na Androida?
2. Konfigurowanie środowiska programistycznego
Przechodzisz z MDC-101?
Jeśli masz ukończony kod MDC-101, Twój kod powinien być gotowy do tego ćwiczenia z programowania. Możesz przejść do kroku 3. Dodaj górny pasek aplikacji.
Zaczynasz od zera?
Pobierz aplikację startową z programowania
Aplikacja startowa znajduje się w katalogu material-components-android-codelabs-102-starter/java
. Pamiętaj, aby przed rozpoczęciem przejść do tego katalogu: cd
.
...lub skopiuj je z GitHuba
Aby skopiować to ćwiczenia z programowania z GitHuba, uruchom te 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
- Gdy kreator zakończy konfigurację i wyświetli się okno Witamy w Android Studio, kliknij Otwórz istniejący projekt Android Studio. Przejdź do katalogu, w którym został zainstalowany przykładowy kod, i wybierz polecenie java -> świątynia (lub wyszukaj na komputerze shrine), aby otworzyć projekt Shrine.
- Poczekaj, aż Android Studio skompiluje i zsynchronizuje projekt, zgodnie ze wskaźnikami aktywności u dołu okna Android Studio.
- W tym momencie Android Studio może zgłaszać 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 aplikacje i zsynchronizować projekt.
Dodaj zależności projektu
Projekt musi być zależny od biblioteki pomocy MDC Android. Ta zależność powinna już być widoczna w pobranym przykładowym kodzie, ale warto wykonać te czynności, aby mieć pewność.
- Przejdź do pliku
build.gradle
modułuapp
i upewnij się, że blokdependencies
zawiera zależność od MDC na Androidzie:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Opcjonalnie) W razie potrzeby zmodyfikuj plik
build.gradle
, aby dodać poniższe zależności i zsynchronizować 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
|
Gotowe! Powinna wyświetlić się strona logowania do Shrine z ćwiczenia z programowania MDC-101.
Teraz gdy ekran logowania wygląda dobrze, dodajmy do aplikacji kilka produktów.
3. Dodaj górny pasek aplikacji
Po zamknięciu strony logowania pojawia się ekran główny z komunikatem „Udało Ci się!”. Wspaniale. Jednak teraz użytkownik nie musi podejmować żadnych działań ani nie ma żadnego wglądu w to, gdzie się znajduje w aplikacji. Aby Ci w tym pomóc, dodajmy nawigację.
Material Design zapewnia dużą wygodę korzystania z nawigacji. Jednym z najważniejszych elementów nawigacji jest górny pasek aplikacji.
Aby zapewnić użytkownikom nawigację i zapewnić szybki dostęp do innych działań, dodajmy górny pasek aplikacji.
Dodawanie widżetu AppBar
Z listy shr_product_grid_fragment.xml
usuń tag <LinearLayout>
zawierający hasło „Udało Ci się!” TextView
i zastąp go następującym:
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
powinien 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 do nas ikonę menu.
Dodawanie ikony nawigacji
Nie wychodząc z interfejsu shr_product_grid_fragment.xml
, do komponentu XML Toolbar
dodanego właśnie do układu dodaj ten kod:
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
shr_product_grid_fragment.xml
powinien 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>
Dodaj przyciski poleceń i określ styl górnego paska aplikacji
Możesz też dodać przyciski na końcu paska aplikacji. Na Androidzie są one nazywane przyciskami polecenia.
Automatycznie dodamy styl do górnego paska aplikacji i dodamy do jego menu przyciski poleceń.
Najpierw utwórzmy metodę konfigurowania paska narzędzi. Metoda powinna uzyskać odwołanie do paska narzędzi za pomocą parametru id
, a także uzyskać odniesienie do aktywności za pomocą parametru getActivity()
. Jeśli aktywność nie ma wartości null, ustaw Toolbar
jako element ActionBar
za pomocą 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, bezpośrednio pod dodaną właśnie metodą setUpToolbar
, zastąpmy onCreateOptionsMenu
, aby rozszerzyć zawartość elementu 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 do metody setUpToolbar
, która została dodana do treści metody onCreateView()
, za pomocą tego kodu:
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 tabeli ProductGridFragment.java
. W treści metody ustaw parametr setHasOptionMenu
na true
.
Powinna ona 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 w pasek działań dla tej aktywności. Wywołanie zwrotne onCreateOptionsMenu
informuje aktywność, której wartości użyć jako menu. W takim przypadku na pasku aplikacji zostaną umieszczone pozycje menu z R.menu.shr_toolbar_menu
.
Plik menu zawiera 2 elementy: „Szukaj” i „Filtruj”.
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 tych 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 na pasku narzędzi są ikona nawigacji, tytuł i dwie ikony działań po prawej stronie. Na pasku narzędzi widoczna jest również wysokość. Wyraźny cień jest wówczas widoczny w innej warstwie niż jej zawartość.
4. Dodaj kartę
Aplikacja ma już strukturę, więc uporządkujmy treści, umieszczając je na kartach.
Dodaj kartę
Zacznijmy od dodania jednej karty poniżej górnego paska aplikacji. Karta powinna zawierać obszar na obraz, tytuł i etykietę dodatkowego tekstu.
W shr_product_grid_fragment.xml
dodaj pod 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>
Kompilacja i uruchamianie:
Na tym podglądzie widać, że karta jest wstawiona od lewej krawędzi ekranu, ma zaokrąglone rogi i cień (odzwierciedlający wysokość karty). Cały obszar jest nazywany „kontenerem”. Oprócz samego kontenera wszystkie elementy w nim są opcjonalne.
Do kontenera możesz dodać te elementy: tekst nagłówka, miniaturę lub awatar, tekst podtytułu, separatory, a nawet przyciski i ikony. Na przykład utworzona przez nas karta zawiera dwa pola TextView
(jeden dla tytułu, a drugi dla tekstu dodatkowego) w dokumencie LinearLayout
, wyrównanym do dołu karty.
Karty zwykle wyświetlają się w kolekcji razem z innymi kartami. W następnej sekcji tego ćwiczenia z programowania umieścimy je jako kolekcję w siatce.
5. Utwórz siatkę kart
Gdy na ekranie znajduje się wiele kart, są one zgrupowane w jedną lub więcej kolekcji. Karty w siatce są w tej samej płaszczyźnie, co oznacza, że znajdują się na tej samej wysokości spoczynkowej co karty (chyba że zostaną wyciągnięte lub przeciągnięte, ale nie będziemy tego omawiać w tym ćwiczeniu).
Konfigurowanie siatki kart
Spójrz na nasz plik shr_product_card.xml
:
shr_product_card.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/product_image"
android:layout_width="match_parent"
android:layout_height="@dimen/shr_product_card_image_height"
android:background="?attr/colorPrimaryDark"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
Ten układ karty zawiera kartę z obrazem (w tym przypadku NetworkImageView
, co pozwala nam dołączyć obrazy z adresu URL) oraz 2 elementy TextViews
.
Następnie zapoznaj się z przygotowanymi przez nas ProductCardRecyclerViewAdapter
. Jest w tym samym pakiecie 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();
}
}
Powyższa klasa adaptera zarządza zawartością naszej siatki. Aby określić, co każdy widok powinien robić z daną treścią, wkrótce napiszemy kod dla onBindViewHolder()
.
W tym samym pakiecie możesz również przyjrzeć się ProductCardViewHolder
. Te zajęcia przechowuje widoki, które wpływają na układ karty, dzięki czemu możemy je później modyfikować.
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ń obiekt 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>
shr_product_grid_fragment.xml
powinien 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 onCreateView()
dodaj kod inicjowania RecyclerView
do ProductGridFragment.java
po wywołaniu 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 inicjowania niezbędne do skonfigurowania RecyclerView
. Obejmuje to wybór menedżera układu RecyclerView
oraz zainicjowanie i ustawienie adaptera RecyclerView
.
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 już są! Nic jeszcze nie wyświetla, więc dodajmy dane o produktach.
Dodawanie obrazów i tekstu
Do każdej karty dodaj zdjęcie, nazwę produktu i cenę. Nasz abstrakcja ViewHolder
obejmuje wyświetlenia każdej karty. W ViewHolder
dodaj te 3 widoki w następujący 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 adapterze RecyclerView
w narzędziu ViewHolder,
zaktualizuj metodę onBindViewHolder()
, aby ustawić informacje w 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 adapter naszego RecyclerView
, co zrobić z każdą kartą przy użyciu ViewHolder
.
Ustawia tutaj dane tekstowe w TextView
ViewHolder
i wywołuje funkcję ImageRequester
, by pobrać obraz z adresu URL. ImageRequester
to zajęcia, które udostępniliśmy dla wygody użytkowników i korzystają z biblioteki Volley
(temat wykracza poza zakres tego ćwiczenia w programowaniu, ale możesz samodzielnie zapoznać się z kodem).
Kompilacja i uruchamianie:
Nasze produkty wyświetlają się teraz w aplikacji.
6. Podsumowanie
Nasza aplikacja ma podstawowa procedurę, która przenosi użytkownika z ekranu logowania na ekran główny, na którym można zobaczyć produkty. W zaledwie kilku linijkach kodu dodaliśmy górny pasek aplikacji z tytułem i 3 przyciskami oraz siatkę kart prezentujących zawartość aplikacji. Nasz ekran główny jest teraz prosty i funkcjonalny, ma podstawową strukturę i zawiera przydatne treści.
Dalsze kroki
Użyliśmy 4 głównych komponentów Material Design z biblioteki MDC-Android na górnym pasku aplikacji, karcie, polu tekstowym i przycisku. Jeszcze więcej komponentów znajdziesz w komponentach MDC na Androida w katalogu MDC-Android.
Jest w pełni funkcjonalna, ale nie promuje jeszcze żadnej marki. W poradniku MDC-103: Material Design Theming with Color, shape, Elevation and Type, dostosujemy styl tych komponentów, aby podkreślić żywą, nowoczesną markę.