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?
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
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
- 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.
- Zaczekaj, aż Android Studio skompiluje i zsynchronizuje projekt, na co wskazują wskaźniki aktywności na dole okna Android Studio.
- 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ć.
- Przejdź do pliku
build.gradle
modułuapp
i upewnij się, że blokdependencies
zawiera zależność w MDC na Androida:
api 'com.google.android.material:material:1.1.0-alpha06'
- (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
|
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".
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
'.
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
'', 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.