1. Введение
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
Компоненты 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.
- После завершения работы мастера установки и появления окна «Добро пожаловать в Android Studio» нажмите « Открыть существующий проект Android Studio» . Перейдите в каталог, в который вы установили пример кода, и выберите kotlin -> shrine (или найдите на своем компьютере shrine ), чтобы открыть проект Shipping.
- Подождите, пока Android Studio создаст и синхронизирует проект, как показывают индикаторы активности в нижней части окна Android Studio.
- На этом этапе Android Studio может вызвать некоторые ошибки сборки, поскольку вам не хватает Android SDK или инструментов сборки, таких как показанный ниже. Следуйте инструкциям в Android Studio, чтобы установить/обновить их и синхронизировать проект.
Добавить зависимости проекта
Проекту нужна зависимость от библиотеки поддержки Android MDC . В загруженном вами примере кода эта зависимость уже должна быть указана, но чтобы убедиться в этом, рекомендуется выполнить следующие шаги.
- Перейдите к файлу
build.gradle
модуляapp
и убедитесь, что блокdependencies
включает зависимость от MDC Android:
api 'com.google.android.material:material:1.1.0-alpha06'
- (Необязательно) При необходимости отредактируйте файл
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' }
Запустите стартовое приложение
|
Успех! Стартовый код для страницы входа в Shrine должен быть запущен в вашем эмуляторе. Вы должны увидеть название «Shrine» и логотип Shrine чуть ниже него.
Давайте посмотрим на код. В нашем примере кода мы предоставили простую структуру навигации 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», который включает в себя встроенные функции отображения плавающей метки и сообщений об ошибках.
Добавьте 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
» в элементе PasswordTextInputEditText
. Это скроет вводимый текст в поле пароля.
С учетом этих изменений текстовые поля в 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>
Теперь попробуйте запустить приложение. Вы должны увидеть страницу с двумя текстовыми полями «Имя пользователя» и «Пароль»!
Посмотрите анимацию плавающей метки:
4. Добавьте кнопки
Далее мы добавим на нашу страницу входа две кнопки: «Отмена» и «Далее». Мы будем использовать компонент MDC Button, который имеет встроенный культовый эффект рукописной ряби Material Design.
Добавьте 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>
Вот и все! Когда вы запустите приложение, при нажатии каждой кнопки будет отображаться рябь от чернил.
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. Мы надеемся, что вам понравилась эта кодовая лаборатория!