MDC-102 Android: структура и макет материала (Java)

logo_components_color_2x_web_96dp.png

Компоненты материалов (MDC) помогают разработчикам реализовать Material Design. Созданный командой инженеров и дизайнеров UX в Google, MDC включает в себя десятки красивых и функциональных компонентов пользовательского интерфейса и доступен для Android, iOS, Интернета и Flutter.

material.io/разработка

В codelab MDC-101 вы использовали два компонента материала (MDC) для создания страницы входа: текстовые поля и кнопки. Теперь давайте расширим эту основу, добавив навигацию, структуру и данные.

Что вы будете строить

В этой лаборатории кода вы создадите домашний экран для приложения Shrine , приложения для электронной коммерции, которое продает одежду и товары для дома. Он будет содержать:

  • Верхняя панель приложений
  • Список продуктов в виде сетки

Компоненты MDC-Android в этой кодовой лаборатории

  • AppBarLayout
  • Материалкарточкавид

Что вам понадобится

  • Базовые знания Android-разработки
  • Android Studio (скачайте здесь , если у вас ее еще нет)
  • Эмулятор или устройство Android (доступно через Android Studio)
  • Пример кода (см. следующий шаг)

Как бы вы оценили свой уровень опыта создания приложений для Android?

Новичок Средний Опытный

Продолжая с MDC-101?

Если вы выполнили MDC-101, ваш код должен быть готов для этой лаборатории кода. Вы можете перейти к шагу 3: добавьте верхнюю панель приложений .

Начиная с нуля?

Загрузите начальное приложение Codelab

Скачать стартовое приложение

Стартовое приложение находится в material-components-android-codelabs-102-starter/java . Обязательно cd в этот каталог перед началом.

...или клонируйте его с GitHub

Чтобы клонировать эту лабораторию кода из GitHub, выполните следующие команды:

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

Загрузите стартовый код в Android Studio

  1. После завершения работы мастера установки и отображения окна « Добро пожаловать в Android Studio » нажмите «Открыть существующий проект Android Studio» . Перейдите в каталог, в который вы установили пример кода, и выберите java -> shrine (или выполните поиск shrine на своем компьютере), чтобы открыть проект Shrine.
  2. Подождите, пока Android Studio создаст и синхронизирует проект, о чем свидетельствуют индикаторы активности в нижней части окна Android Studio.
  3. На этом этапе Android Studio может вызвать некоторые ошибки сборки из-за отсутствия Android SDK или инструментов сборки, таких как показанный ниже. Следуйте инструкциям в Android Studio, чтобы установить/обновить их и синхронизировать свой проект.

Добавить зависимости проекта

Проекту нужна зависимость от библиотеки поддержки MDC Android . В загруженном образце кода эта зависимость уже должна быть указана, но рекомендуется выполнить следующие шаги, чтобы убедиться в этом.

  1. Перейдите к файлу build.gradle модуля app и убедитесь, что блок dependencies включает зависимость от MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (Необязательно) При необходимости отредактируйте файл build.gradle , чтобы добавить следующие зависимости и синхронизировать проект.
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'
}

Запустите стартовое приложение

  1. Убедитесь, что конфигурация сборки слева от кнопки «Выполнить/Воспроизвести»app .
  2. Нажмите зеленую кнопку Run/Play, чтобы создать и запустить приложение.
  3. В окне Select Deployment Target , если у вас уже есть устройство Android, указанное в списке доступных устройств, перейдите к шагу 8 . В противном случае нажмите «Создать новое виртуальное устройство» .
  4. На экране « Выбор оборудования » выберите телефонное устройство, например Pixel 2 , и нажмите « Далее ».
  5. На экране System Image выберите последнюю версию Android , желательно самый высокий уровень API. Если он не установлен, щелкните показанную ссылку « Загрузить » и завершите загрузку.
  6. Нажмите «Далее» .
  7. На экране виртуального устройства Android (AVD) оставьте настройки без изменений и нажмите « Готово ».
  8. Выберите устройство Android в диалоговом окне цели развертывания.
  9. Нажмите «ОК» .
  10. Android Studio создает приложение, развертывает его и автоматически открывает на целевом устройстве.

Успех! Вы должны увидеть страницу входа в Shrine из кодовой лаборатории MDC-101.

Теперь, когда экран входа в систему выглядит хорошо, давайте заполним приложение некоторыми продуктами.

Главный экран открывается, когда страница входа закрывается, с экраном с надписью «Вы сделали это!». Замечательно! Но теперь у нашего пользователя нет действий, которые нужно предпринять, или какого-либо понимания того, где он находится в приложении. Чтобы помочь с этим, давайте добавим навигацию.

Material Design предлагает шаблоны навигации, обеспечивающие высокую степень удобства использования. Одним из наиболее заметных компонентов навигации является верхняя панель приложений.

Чтобы обеспечить навигацию и предоставить пользователям быстрый доступ к другим действиям, давайте добавим верхнюю панель приложения.

Добавьте виджет AppBar

В shr_product_grid_fragment.xml удалите <LinearLayout> , содержащий фразу «Вы сделали это!» TextView и замените его следующим:

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 должен выглядеть следующим образом:

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>

Многие панели приложений имеют кнопку рядом с заголовком. Давайте добавим значок меню к нашему.

Добавить значок навигации

Находясь в shr_product_grid_fragment.xml , добавьте следующее в XML-компонент Toolbar (который вы только что добавили в свой макет):

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

Ваш shr_product_grid_fragment.xml должен выглядеть следующим образом:

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>

Добавьте кнопки действий и стиль верхней панели приложений.

Вы также можете добавить кнопки в конце панели приложения. В Android они называются кнопками действий .

Мы стилизуем верхнюю панель приложения и программно добавим кнопки действий в ее меню.

Во-первых, давайте создадим метод для настройки панели инструментов. Метод должен получить ссылку на панель инструментов, используя ее id , а также получить ссылку на активность, используя getActivity() . Если активность не равна нулю, установите Toolbar для использования в качестве setSupportActionBar ActionBar

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

Затем, непосредственно под только что добавленным методом setUpToolbar , давайте переопределим onCreateOptionsMenu , чтобы раздуть содержимое shr_toolbar_menu.xml на панель инструментов:

ProductGridFragment.java

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

Теперь добавьте вызов метода setUpToolbar , который мы добавили к содержимому метода onCreateView() , со следующим:

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

Наконец, добавьте метод onCreate() в ProductGridFragment.java . В теле метода установите для параметра setHasOptionMenu true .

Метод должен выглядеть так:

ProductGridFragment.java

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

Приведенный выше код устанавливает панель приложения из нашего макета XML в качестве панели действий для этого действия. Обратный вызов onCreateOptionsMenu сообщает активности, что использовать в качестве нашего меню. В этом случае он поместит пункты меню из R.menu.shr_toolbar_menu в панель приложения.

Файл меню содержит два пункта: «Поиск» и «Фильтр».

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>

После этих изменений ваш файл ProductGridFragment.java должен выглядеть следующим образом:

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

}

Стройте и запускайте. Ваш главный экран должен выглядеть так:

Теперь на панели инструментов есть значок навигации, заголовок и два значка действий с правой стороны. Панель инструментов также отображает высоту с помощью тонкой тени, которая показывает, что она находится на другом слое, чем содержимое.

Теперь, когда наше приложение имеет некоторую структуру, давайте организуем содержимое, разместив его на карточках.

Добавьте карту

Давайте начнем с добавления одной карточки под верхнюю панель приложения. Карточка должна иметь область для изображения, заголовок и метку для дополнительного текста.

В shr_product_grid_fragment.xml добавьте следующее под 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>

Соберите и запустите:

В этом предварительном просмотре вы можете видеть, что карта вставлена ​​от левого края экрана, имеет закругленные углы и тень (которая выражает высоту карты). Вся область называется «контейнером». Помимо самого контейнера, все его элементы являются необязательными.

Вы можете добавить в контейнер следующие элементы: текст заголовка, миниатюру или аватар, текст подзаголовка, разделители и даже кнопки и значки. Например, карта, которую мы только что создали, содержит два TextView (один для заголовка и один для дополнительного текста) в LinearLayout , выровненных по нижней части карты.

Карты обычно показываются в коллекции с другими картами. В следующем разделе этой кодовой лаборатории мы разместим их в виде набора в сетке.

Когда на экране присутствует несколько карточек, они группируются в одну или несколько коллекций. Карты в сетке компланарны, то есть они имеют одну и ту же высоту покоя, что и одна другая (если только их не поднять или не перетащить, но мы не будем рассматривать это в этой кодовой лаборатории).

Настройте сетку карт

Взгляните на файл 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>

Этот макет карты содержит карту с изображением (здесь NetworkImageView , что позволяет нам включать изображения из URL-адреса) и два TextViews .

Затем взгляните на ProductCardRecyclerViewAdapter , который мы вам предоставили. Он находится в том же пакете, что и 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();
   }
}

Приведенный выше класс адаптера управляет содержимым нашей сетки. Чтобы определить, что каждое представление должно делать со своим содержимым, мы вскоре напишем код для onBindViewHolder() .

В том же пакете вы также можете взглянуть на ProductCardViewHolder . Этот класс хранит представления, которые влияют на макет нашей карты, поэтому мы можем изменить их позже.

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

Чтобы настроить нашу сетку, сначала мы хотим удалить заполнитель MaterialCardView из shr_product_grid_fragment.xml . Далее вы должны добавить компонент, представляющий нашу сетку карточек. В этом случае добавьте компонент RecyclerView в файл shr_product_grid_fragment.xml под 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 должен выглядеть следующим образом:

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>

Наконец, в onCreateView() добавьте код инициализации RecyclerView в ProductGridFragment.java после вызова setUpToolbar(view) и перед оператором 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;
}

Приведенный выше фрагмент кода содержит необходимые шаги инициализации для настройки RecyclerView . Это включает в себя настройку диспетчера компоновки RecyclerView , а также инициализацию и настройку адаптера RecyclerView .

Теперь ваш файл ProductGridFragment.java должен выглядеть следующим образом:

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

}

Стройте и запускайте.

Карты уже есть! Они пока ничего не показывают, поэтому давайте добавим некоторые данные о продукте.

Добавьте изображения и текст

Для каждой карты добавьте изображение, название продукта и цену. Наша абстракция ViewHolder содержит представления для каждой карты. В нашем ViewHolder добавьте три вида следующим образом:

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

В нашем адаптере RecyclerView в ViewHolder, обновите метод onBindViewHolder() , чтобы установить информацию о каждом представлении:

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

Приведенный выше код сообщает нашему адаптеру RecyclerView , что делать с каждой картой, используя ViewHolder .

Здесь он устанавливает текстовые данные для каждого из TextView ViewHolder и вызывает ImageRequester для получения изображения из URL-адреса. ImageRequester — это класс, который мы предоставили для вашего удобства, и он использует библиотеку Volley (это тема, выходящая за рамки данной лаборатории кода, но не стесняйтесь исследовать код самостоятельно).

Соберите и запустите:

Наши продукты теперь отображаются в приложении!

Наше приложение имеет базовый процесс, который переводит пользователя с экрана входа в систему на главный экран, где можно просмотреть продукты. Всего несколькими строками кода мы добавили верхнюю панель приложения с заголовком и тремя кнопками, а также сетку карточек для представления содержимого нашего приложения. Наш домашний экран теперь простой и функциональный, с базовой структурой и активным содержимым.

Следующие шаги

С верхней панелью приложения, карточкой, текстовым полем и кнопкой мы теперь использовали четыре основных компонента Material Design из библиотеки MDC-Android! Вы можете изучить еще больше компонентов в компонентах каталога MDC-Android в MDC Android .

Несмотря на то, что оно полностью функционально, наше приложение еще не представляет какой-либо конкретный бренд. В MDC-103: Material Design Theming with Color, Shape, Elevation и Type мы настроим стиль этих компонентов, чтобы выразить яркий современный бренд.

Я смог завершить эту лабораторную работу с разумным количеством времени и усилий.

Полностью согласен Соглашаться Нейтральный Не согласен Категорически не согласен

Я хотел бы продолжать использовать Material Components в будущем

Полностью согласен Соглашаться Нейтральный Не согласен Категорически не согласен