Разработка программного обеспечения для Android: Jetpack Compose и Material 3 реализуют расширенную страницу входа (Kotlin)
Разработка программного обеспечения для Android: Jetpack Compose и Material 3 реализуют расширенную страницу входа (Kotlin)

Уже середина 2024 года. Как глухой независимый разработчик, я часто время от времени размышляю о себе: какого прогресса я достиг за последние шесть месяцев? В этой статье я расскажу о случае реализации страницы входа с использованием Jetpack Compose, Material3 и языка Kotlin. Если у вас есть некоторый опыт разработки, я думаю, эта статья будет вам очень полезна.

1. Предыстория проекта

Material 3 — это новейшая платформа пользовательского интерфейса Google. Она заменяет традиционную структуру XML декларативным методом построения пользовательского интерфейса, что значительно повышает эффективность программирования и сокращает объем утомительного кода. В этом проекте для реализации страницы входа используются языки Compose, Material 3 и Kotlin.

PS: Подходит для разработчиков с существующей базой программирования.,Если вы новичок,Рекомендуется сначала прочитать другую мою основную статью.:Разработка программного обеспечения для Android: используйте Java и Kotlin для создания инфраструктуры MDC-UI для реализации LoginUI (базовый уровень) — Сообщество разработчиков Tencent Cloud — Tencent Cloud (tencent.com)

1.1 Анализ требований проекта

Базовая структура страницы входа:

Два текстовых поля:Используется для ввода имени пользователяипароль。

две кнопки:соответственно“Cancel”кнопкаи“Next”кнопка。

2. Разработка проекта

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

Добавьте зависимости для Compose и Material 3 в файл build.gradle вашего проекта:

Язык кода:groovy
копировать
dependencies {
    implementation libs.androidx.core.ktx
    implementation libs.androidx.lifecycle.runtime.ktx
    implementation libs.androidx.activity.compose
    implementation platform(libs.androidx.compose.bom)
    implementation libs.androidx.ui
    implementation libs.androidx.ui.graphics
    implementation libs.androidx.ui.tooling.preview
    implementation libs.androidx.material3
    testImplementation libs.junit
    androidTestImplementation libs.androidx.junit
    androidTestImplementation libs.androidx.espresso.core
    androidTestImplementation platform(libs.androidx.compose.bom)
    androidTestImplementation libs.androidx.ui.test.junit4
    debugImplementation libs.androidx.ui.tooling
    debugImplementation libs.androidx.ui.test.manifest
}

[versions]
agp = "8.6.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.3"
activityCompose = "1.9.0"
composeBom = "2024.04.01"

//grade/libs.versions.toml
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

2.2 Инициализация проекта Compose

После загрузки и добавления зависимостей убедитесь, что проект настроен для использования Jetpack Compose, и запустите пользовательский интерфейс, настроив MainActivity для привязки его в стиле Compose:

Язык кода:java
копировать
@Composable
fun MainScreen() {
    Scaffold {
        LoginScreen()
    }
}

2.3 Создать страницу входа

Язык кода:java
копировать
@Composable
fun LoginScreen() {
    var username by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    var error by remember { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Nim", style = MaterialTheme.typography.displayMedium)

        Spacer(modifier = Modifier.height(16.dp))

        TextField(
            value = username,
            onValueChange = { username = it },
            label = { Text("Username") },
            singleLine = true
        )

        Spacer(modifier = Modifier.height(16.dp))

        TextField(
            value = password,
            onValueChange = { password = it },
            label = { Text("Password") },
            singleLine = true,
            visualTransformation = PasswordVisualTransformation()
        )

        if (error.isNotEmpty()) {
            Text(text = error, color = Color.Red, style = MaterialTheme.typography.bodyMedium)
        }

        Spacer(modifier = Modifier.height(16.dp))

        Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
            Button(onClick = { }) {
                Text("Cancel")
            }

            Button(onClick = {
                if (password.length < 8) {
                    error = «Пароль должен содержать не менее 8 символов».
                } else {
                    error = ""
                }
            }) {
                Text("Next")
            }
        }
    }
}

2.4 Введение в обзор знаний

Это позволяет вам видеть написанные вами компоненты пользовательского интерфейса в реальном времени в Android Studio без необходимости каждый раз перезапускать приложение. Это очень помогает нам при отладке и настройке интерфейса.

2.4.1 Базовое использование @Preview

@Preview Аннотации обычно используются в @Composable Над функцией, используется для обозначения функции UI Макет можно найти в Android Studio отображается в окне предварительного просмотра. Вот базовая структура функции предварительного просмотра:

Язык кода:java
копировать
@Preview(showBackground = true)
@Composable
fun LoginScreenPreview() {
    NimLoginTheme {
        LoginScreen()
    }
}

@Preview Как маленькое окно, которое поможет нам показать @Composable Фактический эффект рендеринга функции. Просто добавьте его над кодом @Preview,Просто будь там Android Studio С правой стороны вы можете увидеть эффект пользовательского интерфейса, который хотите увидеть.

2.5 Рендеринг

2.6 Полный код

Язык кода:java
копировать
package com.nim.nimlogin

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.nim.nimlogin.ui.theme.NimLoginTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            NimLoginTheme {
                LoginScreen()
            }
        }
    }
}

@Composable
fun LoginScreen() {
    var username by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    var error by remember { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Nim", style = MaterialTheme.typography.displayMedium)

        Spacer(modifier = Modifier.height(16.dp))

        TextField(
            value = username,
            onValueChange = { username = it },
            label = { Text("Username") },
            singleLine = true
        )

        Spacer(modifier = Modifier.height(16.dp))

        TextField(
            value = password,
            onValueChange = { password = it },
            label = { Text("Password") },
            singleLine = true,
            visualTransformation = PasswordVisualTransformation()
        )

        if (error.isNotEmpty()) {
            Text(text = error, color = Color.Red, style = MaterialTheme.typography.bodyMedium)
        }

        Spacer(modifier = Modifier.height(16.dp))

        Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
            Button(onClick = {
                // очистить ввод
                username = ""
                password = ""
                error = ""
            }) {
                Text("Cancel")
            }

            Button(onClick = {
                if (password.length < 8) {
                    error = «Пароль должен содержать не менее 8 символов».
                } else {
                    error = ""
                }
            }) {
                Text("Next")
            }
        }
    }
}
@Preview(showBackground = true)
@Composable
fun LoginScreenPreview() {
    NimLoginTheme {
        LoginScreen()
    }
}

2.7 видеодемонстрация выглядит следующим образом:

3. Технические трудности

3.1 Управление статусом пользовательского интерфейса и обратная связь в режиме реального времени

трудность:и Традиция XML Различное управление состоянием, Compose использовать remember и mutableStateOf управлять UI состояние. Как обновить интерфейс в режиме реального времени, чтобы обеспечить удобство ввода данных пользователем.

решение:использовать remember и mutableStateOf Поддерживайте состояние компонента, чтобы гарантировать автоматическое обновление интерфейса при изменении состояния.

3.2 Проверка ввода и сообщения об ошибках

трудность:Обеспечивает проверку ввода в реальном времени и удобен для пользователя.из Сообщение об ошибке,Предотвратите задержку или потерю статуса ошибки.

решение:существовать onValueChange Выполняйте проверку ввода и улучшайте взаимодействие с пользователем за счет динамического обновления сообщений об ошибках. использовать Text и Color В этом сочетании вам следует больше подумать о том, как разработать интуитивно понятный стиль подсказок об ошибках.

3.3 Декларативная навигация и разделение компонентов

трудность:существовать Compose Средняя, ​​декларативная и традиционная навигация Fragment и Activity Есть большая разница в навигации, особенно в статусе и сохранении и восстановлении.

решение:использовать Navigation Compose Перейдите на страницу управлять, NavHost Реализуйте страницу развязки и управления состоянием, чтобы UI Процесс более плавный, а обслуживание легкое.

4. Заметки об исследовании

Я провел свою любовь к Jetpack Compose из Understand, а также освоил, как гибко использовать и управлять компонентами в реальном проекте. Стоит поделиться своим опытом:

  1. Преимущества декларативного программирования:Compose Сократите количество избыточного кода с помощью декларативного программирования. UI Логика тесно связана с состоянием, что делает разработку более интуитивной.
  2. Material 3 Компоненты и Compose сочетание:Material 3 Предоставляет множество современных UI компоненты, такие как ScaffoldTopAppBar Подождите, опыт очень хороший, давайте UI Более красивый и последовательный.
  3. упрощенный UI 状态управлять:Compose из State управлять по сравнению с традиционным из LiveData и ViewModel Более гибкий и лучше интегрированный в UI интерактивная сцена.

5. Резюме и перспективы

Благодаря практике этой статьи я испытал Jetpack Compose Мощные преимущества Jetpack: Декларативное программирование Compose делает его интуитивно понятным и упрощенным. UI Строить, гибко управлять статусом и Material 3 Мощность компонентов. Это дает мне большие надежды на будущее развитие. полагать Jetpack Compose в ближайшие несколько лет стать Android UI Разработаны основные инструменты, надеюсь, эта статья будет полезна всем! !

6. Мое портфолио

Для справки см. GitHub. склад - GitHub - jienian/CHAPTS,Содержимое включает Kotlin, ComposeM3. Подождите, пока технология будет реализована.

Не стесняйтесь задавать любые вопросы, спасибо всем, кто дочитал)

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose