Разработка программного обеспечения для 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
Как использовать PaddleOCRSharp в рамках .NET
boy illustration
CRUD используется уже два или три года. Как читать исходный код Spring?
boy illustration
Устраните проблему совместимости между версией Spring Boot и Gradle Java: возникла проблема при настройке корневого проекта «demo1» > Не удалось.
boy illustration
Научите вас шаг за шагом, как настроить Nginx.
boy illustration
Это руководство — все, что вам нужно для руководства по автономному развертыванию сервера для проектов Python уровня няни (рекомендуемый сборник).
boy illustration
Не удалось запустить docker.service — Подробное объяснение идеального решения ️
boy illustration
Настройка файлового сервера Samba в системе Linux Centos. Анализ NetBIOS (супер подробно)
boy illustration
Как настроить метод ssh в Git, как получить и отправить код через метод ssh
boy illustration
RasaGpt — платформа чат-ботов на основе Rasa и LLM.
boy illustration
Nomic Embed: воспроизводимая модель внедрения SOTA с открытым исходным кодом.
boy illustration
Улучшение YOLOv8: EMA основана на эффективном многомасштабном внимании, основанном на межпространственном обучении, и эффект лучше, чем у ECA, CBAM и CA. Малые цели имеют очевидные преимущества | ICASSP2023
boy illustration
Урок 1 серии Libtorch: Тензорная библиотека Silky C++
boy illustration
Руководство по локальному развертыванию Stable Diffusion: подробные шаги и анализ распространенных проблем
boy illustration
Полностью автоматический инструмент для работы с видео в один клик: VideoLingo
boy illustration
Улучшения оптимизации RT-DETR: облегченные улучшения магистрали | Support Paddle облегченный rtdetr-r18, rtdetr-r34, rtdetr-r50, rtdet
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | Деформируемое внимание с большим ядром (D-LKA Attention), большое ядро ​​​​свертки улучшает механизм внимания восприимчивых полей с различными функциями
boy illustration
Создано Datawhale: выпущено «Руководство по тонкой настройке развертывания большой модели GLM-4»!
boy illustration
7B превышает десятки миллиардов, aiXcoder-7B с открытым исходным кодом Пекинского университета — это самая мощная модель большого кода, лучший выбор для корпоративного развертывания.
boy illustration
Используйте модель Huggingface, чтобы заменить интерфейс внедрения OpenAI в китайской среде.
boy illustration
Оригинальные улучшения YOLOv8: несколько новых улучшений | Сохранение исходной информации — алгоритм отделяемой по глубине свертки (MDSConv) |
boy illustration
Второй пилот облачной разработки | Быстро поиграйте со средствами разработки на базе искусственного интеллекта
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция с нулевым кодированием и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
Решенная Ошибка | Загрузка PyTorch медленная: TimeoutError: [Errno 110] При загрузке факела истекло время ожидания — Cat Head Tiger
boy illustration
Brother OCR, библиотека с открытым исходным кодом для Python, которая распознает коды проверки.
boy illustration
Новейшее подробное руководство по загрузке и использованию последней демонстрационной версии набора данных COCO.
boy illustration
Выпущен отчет о крупной модели финансовой отрасли за 2023 год | Полный текст включен в загрузку |
boy illustration
Обычные компьютеры также могут работать с большими моделями, и вы можете получить личного помощника с искусственным интеллектом за три шага | Руководство для начинающих по локальному развертыванию LLaMA-3
boy illustration
Одной статьи достаточно для анализа фактора транскрипции SCENIC на Python (4)
boy illustration
Бросая вызов ограничениям производительности небольших видеокарт, он научит вас запускать большие модели глубокого обучения с ограниченными ресурсами, а также предоставит полное руководство по оценке и эффективному использованию памяти графического процессора!
boy illustration
Команда Fudan NLP опубликовала 80-страничный обзор крупномасштабных модельных агентов, в котором в одной статье представлен обзор текущего состояния и будущего агентов ИИ.