MDC-101 Android: основы материальных компонентов (MDC) (Java)

1. Введение

logo_comComponents_color_2x_web_96dp.png

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

Что такое Material Design и Material Components для Android?

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

Что касается приложений Android, Material Components for Android ( MDC Android ) объединяет дизайн и разработку с библиотекой компонентов для обеспечения согласованности всего вашего приложения. По мере развития системы Material Design эти компоненты обновляются, чтобы обеспечить согласованную реализацию с точностью до пикселя и соответствие стандартам внешней разработки Google. MDC также доступен для Интернета, iOS и Flutter.

В этой лаборатории кода вы создадите страницу входа в систему, используя несколько компонентов MDC Android.

Что ты построишь

Эта лаборатория кода — первая из четырех лабораторий кода, которые помогут вам создать приложение под названием Shrine — Android-приложение для электронной коммерции, которое продает одежду и товары для дома. Он продемонстрирует, как можно настроить компоненты в соответствии с любым брендом или стилем с помощью MDC-Android.

В этой лаборатории кода вы создадите страницу входа в Shrine, содержащую:

  • Два текстовых поля: одно для ввода имени пользователя, другое для пароля.
  • Две кнопки: одна для «Отменить», другая для «Далее».
  • Название приложения (Святыня)
  • Изображение логотипа Shrine

4cb0c218948144b4.png

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

  • Текстовое поле
  • Кнопка

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

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

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

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

2. Настройте среду разработки

Запустите Android Studio

Когда вы открываете Android Studio , должно появиться окно под названием «Добро пожаловать в Android Studio». Однако если вы запускаете Android Studio впервые, выполните шаги мастера установки Android Studio со значениями по умолчанию . Этот шаг может занять несколько минут для загрузки и установки необходимых файлов, поэтому не стесняйтесь оставить этот процесс в фоновом режиме, пока вы выполняете следующий раздел.

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

Стартовое приложение находится в каталоге material-components-android-codelabs-101-starter/java .

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

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

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

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

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

F5H6srsw_5xOPGFpKrm1RwgewatxA_HUbDI1PWoQUAoJcT6DpfBOkAYwq3S-2vUHvweUaFgAmG7BtUKkGouUbhTwXQh53qec8tO5eVecdlo7QIoLc8rNxFEBb8l7RlS-KzBbZOzVhA

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

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

  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. Нажмите зеленую кнопку «Выполнить/Воспроизвести», чтобы создать и запустить приложение.
  3. Если в окне «Выбор цели развертывания» у вас уже есть устройство Android в списке доступных устройств, перейдите к шагу 8 . В противном случае нажмите «Создать новое виртуальное устройство» .
  4. На экране «Выбор оборудования» выберите телефонное устройство, например Pixel 2 , и нажмите «Далее» .
  5. На экране «Образ системы» выберите последнюю версию Android , желательно самого высокого уровня API. Если он не установлен, щелкните появившуюся ссылку «Загрузить» и завершите загрузку.
  6. Нажмите Далее .
  7. На экране виртуального устройства Android (AVD) оставьте настройки без изменений и нажмите « Готово» .
  8. Выберите устройство Android в диалоговом окне цели развертывания.
  9. Нажмите «ОК» .
  10. Android Studio создает приложение, развертывает его и автоматически открывает на целевом устройстве.

Успех! Стартовый код для страницы входа в Shrine должен быть запущен в вашем эмуляторе. Вы должны увидеть название «Shrine» и логотип Shrine чуть ниже него.

e7ed014e84755811.png

Давайте посмотрим на код. В нашем примере кода мы предоставили простую структуру навигации Fragment для отображения фрагментов и навигации между ними.

Откройте MainActivity.java в каталоге shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.java.shrine . Он должен содержать это:

MainActivity.java

package com.google.codelabs.mdc.java.shrine;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

public class MainActivity extends AppCompatActivity implements NavigationHost {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.shr_main_activity);

       if (savedInstanceState == null) {
           getSupportFragmentManager()
                   .beginTransaction()
                   .add(R.id.container, new LoginFragment())
                   .commit();
       }
   }

   /**
    * Navigate to the given fragment.
    *
    * @param fragment       Fragment to navigate to.
    * @param addToBackstack Whether or not the current fragment should be added to the backstack.
    */
   @Override
   public void navigateTo(Fragment fragment, boolean addToBackstack) {
       FragmentTransaction transaction =
               getSupportFragmentManager()
                       .beginTransaction()
                       .replace(R.id.container, fragment);

       if (addToBackstack) {
           transaction.addToBackStack(null);
       }

       transaction.commit();
   }
}

Это действие отображает файл макета R.layout.shr_main_activity , определенный в shr_main_activity.xml .

Вы можете видеть, что в onCreate(), MainActivity.java запускает транзакцию Fragment , чтобы отобразить LoginFragment . LoginFragment. Это то, что мы будем модифицировать в этой кодовой лаборатории. Действие также реализует метод navigateTo(Fragment) , определенный в NavigationHost , который позволяет любому фрагменту перейти к другому фрагменту.

Command + Click (или Control + Click ) shr_main_activity в файле активности, чтобы открыть файл макета, или перейдите к файлу макета в app -> res -> layout -> shr_main_activity.xml .

shr_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity" />

Здесь мы видим простой <FrameLayout> , который действует как контейнер для любых фрагментов, отображаемых действием. Давайте откроем LoginFragment.java .

ЛогинФрагмент.java

package com.google.codelabs.mdc.java.shrine;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

/**
* Fragment representing the login screen for Shrine.
*/
public class LoginFragment extends Fragment {

   @Override
   public View onCreateView(
           @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       // Inflate the layout for this fragment
       View view = inflater.inflate(R.layout.shr_login_fragment, container, false);

       // Snippet from "Navigate to the next Fragment" section goes here.

       return view;
   }

   // "isPasswordValid" from "Navigate to the next Fragment" section method goes here
}

LoginFragment раздувает файл макета shr_login_fragment и отображает его в onCreateView() . Давайте посмотрим на файл макета shr_login_fragment.xml чтобы увидеть, как выглядит страница входа.

shr_login_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
   android:background="@color/loginPageBackgroundColor"
   tools:context=".LoginFragment">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:clipChildren="false"
       android:clipToPadding="false"
       android:orientation="vertical"
       android:padding="24dp"
       android:paddingTop="16dp">

       <ImageView
           android:layout_width="64dp"
           android:layout_height="64dp"
           android:layout_gravity="center_horizontal"
           android:layout_marginTop="48dp"
           android:layout_marginBottom="16dp"
           app:srcCompat="@drawable/shr_logo" />

       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:layout_marginBottom="132dp"
           android:text="@string/shr_app_name"
           android:textAllCaps="true"
           android:textSize="16sp" />

       <!-- Snippet from "Add text fields" section goes here. -->

       <!-- Snippet from "Add buttons" section goes here. -->

   </LinearLayout>
</ScrollView>

Здесь мы видим <LinearLayout> с <ImageView> вверху, представляющим логотип Shrine.

После этого идет тег <TextView> , представляющий метку «SHRINE». Текст этой метки представляет собой строковый ресурс с именем @string/shr_app_name . Если вы нажмете Command + Click (или Control + Click ) по имени строкового ресурса или откроете app -> res -> values -> strings.xml , вы увидите файл strings.xml , в котором определены строковые ресурсы. Когда в будущем будут добавлены дополнительные строковые ресурсы, они будут определены здесь. Каждый ресурс в этом файле должен иметь префикс shr_ обозначающий, что он является частью приложения Shrine.

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

3. Добавьте текстовые поля

Для начала мы добавим на нашу страницу входа в систему два текстовых поля, чтобы люди могли вводить свое имя пользователя и пароль. Мы будем использовать компонент «Текстовое поле MDC», который включает в себя встроенные функции отображения плавающей метки и сообщений об ошибках.

d83c47fb4aed3a82.png

Добавьте XML

В shr_login_fragment.xml добавьте два элемента TextInputLayout с дочерним элементом TextInputEditText внутри <LinearLayout> под меткой «SHRINE» <TextView> :

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="text"
       android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

Приведенный выше фрагмент представляет два текстовых поля, каждое из которых состоит из элемента <TextInputLayout> и дочернего элемента <TextInputEditText> . Текст подсказки для каждого текстового поля указан в атрибуте android:hint .

Мы добавили два новых строковых ресурса для текстового поля — @string/shr_hint_username и @string/shr_hint_password . Откройте strings.xml , чтобы увидеть эти строковые ресурсы.

строки.xml

...
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
...

Добавить проверку ввода

Компоненты TextInputLayout предоставляют встроенную функцию обратной связи об ошибках.

Чтобы отобразить обратную связь об ошибках, внесите следующие изменения в shr_login_fragment.xml :

  • Установите app:errorEnabled значение true в элементе TextInputLayout пароля . Это добавит дополнительное дополнение к сообщению об ошибке под текстовым полем.
  • Установите для атрибута android:inputType значение « textPassword » в элементе Password TextInputEditText . Это скроет вводимый текст в поле пароля.

С учетом этих изменений текстовые поля в shr_login_fragment.xml должны выглядеть следующим образом:

shr_login_fragment.xml

<com.google.android.material.textfield.TextInputLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_username">

   <com.google.android.material.textfield.TextInputEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="text"
       android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/password_text_input"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="4dp"
   android:hint="@string/shr_hint_password"
   app:errorEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/password_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>

Теперь попробуйте запустить приложение. Вы должны увидеть страницу с двумя текстовыми полями «Имя пользователя» и «Пароль»!

Посмотрите анимацию плавающей метки:

333184b615aed4f7.gif

4. Добавьте кнопки

Далее мы добавим на нашу страницу входа две кнопки: «Отмена» и «Далее». Мы будем использовать компонент MDC Button, который имеет встроенный культовый эффект рукописной ряби Material Design.

4cb0c218948144b4.png

Добавьте XML

В shr_login_fragment.xml добавьте <RelativeLayout> в <LinearLayout> под элементами TextInputLayout . Затем добавьте два элемента <MaterialButton> в <RelativeLayout> .

Результирующий XML-файл должен выглядеть следующим образом:

shr_login_fragment.xml

<RelativeLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <com.google.android.material.button.MaterialButton
       android:id="@+id/next_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentEnd="true"
       android:layout_alignParentRight="true"
       android:text="@string/shr_button_next" />

   <com.google.android.material.button.MaterialButton
       android:id="@+id/cancel_button"
       style="@style/Widget.MaterialComponents.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginEnd="12dp"
       android:layout_marginRight="12dp"
       android:layout_toStartOf="@id/next_button"
       android:layout_toLeftOf="@id/next_button"
       android:text="@string/shr_button_cancel" />

</RelativeLayout>

Вот и все! Когда вы запустите приложение, при нажатии на каждую кнопку будет отображаться рябь от чернил.

9dd162d65e4a92a2.gif

5. Перейдите к следующему фрагменту.

Наконец, мы добавим Java-код в LoginFragment.java , чтобы подключить нашу кнопку «ДАЛЕЕ» к другому фрагменту. Вы заметите, что каждому из компонентов, которые мы добавили в наш макет, был присвоен id . Мы будем использовать эти id для ссылки на компоненты в нашем коде и добавим некоторую проверку ошибок и навигацию.

Давайте добавим частный логический метод isPasswordValid в LoginFragment.java под onCreateView() с логикой, позволяющей определить, действителен ли пароль. Для целей этой демонстрации мы просто убедимся, что длина пароля составляет не менее 8 символов:

ЛогинФрагмент.java

/*
   In reality, this will have more complex logic including, but not limited to, actual
   authentication of the username and password.
*/
private boolean isPasswordValid(@Nullable Editable text) {
   return text != null && text.length() >= 8;
}

Затем добавьте прослушиватель кликов к кнопке «Далее», который устанавливает и очищает ошибку на основе только что созданного нами метода isPasswordValid() . В onCreateView() этот прослушиватель кликов должен быть помещен между строкой надувателя и строкой return view .

Далее, давайте добавим к паролю прослушиватель ключей TextInputEditText чтобы прослушивать ключевые события, которые устранят ошибку. Этот прослушиватель также должен использовать isPasswordValid() чтобы проверить, действителен ли пароль. Вы можете добавить это непосредственно под прослушивателем кликов в onCreateView() .

Ваш метод onCreateView() теперь должен выглядеть примерно так:

ЛогинФрагмент.java

@Override
public View onCreateView(
       @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   // Inflate the layout for this fragment
   View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
   final TextInputLayout passwordTextInput = view.findViewById(R.id.password_text_input);
   final TextInputEditText passwordEditText = view.findViewById(R.id.password_edit_text);
   MaterialButton nextButton = view.findViewById(R.id.next_button);

   // Set an error if the password is less than 8 characters.
   nextButton.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
           if (!isPasswordValid(passwordEditText.getText())) {
               passwordTextInput.setError(getString(R.string.shr_error_password));
           } else {
               passwordTextInput.setError(null); // Clear the error
           }
       }
   });

   // Clear the error once more than 8 characters are typed.
   passwordEditText.setOnKeyListener(new View.OnKeyListener() {
       @Override
       public boolean onKey(View view, int i, KeyEvent keyEvent) {
           if (isPasswordValid(passwordEditText.getText())) {
               passwordTextInput.setError(null); //Clear the error
           }
           return false;
       }
   });
   return view;
}            

Теперь мы можем перейти к другому фрагменту. Обновите OnClickListener в onCreateView() чтобы перейти к другому фрагменту при успешной проверке ошибок. Это можно сделать, добавив следующую строку для перехода к ProductGridFragment в else прослушивателя кликов:

ЛогинФрагмент.java

...
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
...

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

ЛогинФрагмент.java

...
MaterialButton nextButton = view.findViewById(R.id.next_button);

// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       if (!isPasswordValid(passwordEditText.getText())) {
           passwordTextInput.setError(getString(R.string.shr_error_password));
       } else {
           passwordTextInput.setError(null); // Clear the error
           ((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
       }
   }
});
...

Эта новая строка кода вызывает метод navigateTo() из MainActivity для перехода к новому фрагменту — ProductGridFragment . В настоящее время это пустая страница, над которой вы будете работать в MDC-102.

Теперь создайте приложение. Идем дальше и нажимаем кнопку «Далее».

Вы сделали это! Этот экран станет отправной точкой нашей следующей лаборатории кода, над которой вы будете работать в MDC-102.

6. Все готово

Используя базовую XML-разметку и около 30 строк Java, библиотека Material Components для Android помогла вам создать красивую страницу входа, которая соответствует рекомендациям Material Design, а также одинаково выглядит и ведет себя на всех устройствах.

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

Текстовое поле и кнопка — это два основных компонента библиотеки MDC Android, но их гораздо больше! Остальные компоненты MDC Android вы можете изучить. Альтернативно, перейдите к MDC 102: Структура и макет Material Design, чтобы узнать о верхней панели приложения, представлении карточек и макете сетки. Спасибо за попытку использования Material Components. Мы надеемся, что вам понравилась эта кодовая лаборатория!

Мне удалось завершить эту кодовую работу, потратив разумное количество времени и усилий.

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

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

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