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

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/kotlin .

...или клонируйте его с 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» . Перейдите в каталог, в который вы установили пример кода, и выберите kotlin -> shrine (или найдите на своем компьютере shrine ), чтобы открыть проект Shipping.
  2. Подождите, пока Android Studio создаст и синхронизирует проект, как показывают индикаторы активности в нижней части окна Android Studio.
  3. На этом этапе Android Studio может вызвать некоторые ошибки сборки, поскольку вам не хватает Android SDK или инструментов сборки, таких как показанный ниже. Следуйте инструкциям в Android Studio, чтобы установить/обновить их и синхронизировать проект.

KzoYWC1S7Se7yL8igi1vXF_mbVxAdl2lg5kb7RODrsVpEng0G6U3NK1Qnn0faBBZd2u71yMXioy9tD-7fv3NXvVO4N3EtMMeWDTmqBMMl6egd9R5uXX0T_SKmahbmRor3wZZHX0ByA

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

Проекту нужна зависимость от библиотеки поддержки 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.kt в каталоге shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine . Он должен содержать это:

MainActivity.kt

package com.google.codelabs.mdc.kotlin.shrine

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

class MainActivity : AppCompatActivity(), NavigationHost {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.shr_main_activity)

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

   override fun navigateTo(fragment: Fragment, addToBackstack: Boolean) {
       val transaction = supportFragmentManager
               .beginTransaction()
               .replace(R.id.container, fragment)

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

       transaction.commit()
   }
}

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

Вы можете видеть, что в onCreate(), MainActivity.kt запускает транзакцию 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.kt .

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

package com.google.codelabs.mdc.kotlin.shrine

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

class LoginFragment : Fragment() {

   override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       return view
   }
}

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" />
   </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" />
</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" />
</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. Перейдите к следующему фрагменту.

Наконец, мы добавим код Kotlin в LoginFragment.kt , чтобы подключить нашу кнопку «ДАЛЕЕ» для перехода к другому фрагменту.

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

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

private fun isPasswordValid(text: Editable?): Boolean {
   return text != null && text.length >= 8
}

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

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

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

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

override fun onCreateView(
           inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       // Inflate the layout for this fragment.
       val view = inflater.inflate(R.layout.shr_login_fragment, container, false)

       // Set an error if the password is less than 8 characters.
       view.next_button.setOnClickListener({
           if (!isPasswordValid(password_edit_text.text!!)) {
               password_text_input.error = getString(R.string.shr_error_password)
           } else {
               // Clear the error.
               password_text_input.error = null
           }
       })

       // Clear the error once more than 8 characters are typed.
       view.password_edit_text.setOnKeyListener({ _, _, _ ->
           if (isPasswordValid(password_edit_text.text!!)) {
               // Clear the error.
               password_text_input.error = null
           }
           false
       })

       return view
   }
}

Теперь мы можем перейти к другому фрагменту. В onCreateView() обновите OnClickListener для перехода к другому фрагменту при успешной проверке ошибок. Ваш код clickListener теперь должен выглядеть следующим образом:

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

// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
   if (!isPasswordValid(password_edit_text.text!!)) {
       password_text_input.error = getString(R.string.shr_error_password)
   } else {
       // Clear the error.
       password_text_input.error = null
       // Navigate to the next Fragment.
       (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
   }
})

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

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

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

6. Все готово

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

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

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

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

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

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

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