Android Jetpack Compose 新手教程

啥好人大年三十写博客,哈哈哈,我就是...

最近学习了Compose,话说实践才是更快学习的方式。今天用Compose写一个注册登录页。

什么是Android Jetpack Compose

官网上解释的更全面,什么声明式UI呀。我个人理解就是Android用于构建UI的工具包。它简化并加速了Android上的UI开发。但是为了使用它进行开发呢,你需要了解Kotlin。

那么废话不多说,创建一个新的Android项目。

一、创建一个新的Android Compose项目

首先打开Android Studio并创建一个新项目。我使用的Android Studio版本是Android Studio Hedgehog | 2023.1.1 Patch 2,选择"Empty Activity"并点击"Next"。

接下来您将看到以下界面,输入"FormExample"作为项目名称,然后点击"Finish"。

二、添加所需的包

我们将在本实例中使用navigation-compose,因此打开模块build.gradle文件并添加以下实现:

scss 复制代码
implementation("androidx.navigation:navigation-compose:2.7.0")

三、创建MainActivity

同步您的项目并打开MainActivity.kt

粘贴/输入以下代码:

kotlin 复制代码
package com.example.formexample

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.formexample.pages.ForgotPassword
import com.example.formexample.pages.LoginPage
import com.example.formexample.pages.SignUp
import com.example.formexample.ui.theme.FormExampleTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FormExampleTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    ScreenMain()
                }
            }
        }
    }
}

@Composable
fun ScreenMain() {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = "login") {
        composable("login") { LoginPage(navController) }
        composable("signup") { SignUp(navController) }
        composable("forgot-password") { ForgotPassword(navController) }
    }
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    FormExampleTheme {
        ScreenMain()
    }
}

这里我们基本上设置了主屏幕,导航控制器可以在多个页面之间进行导航。跟页面是登录屏幕。此时不要担心任何错误,因为我们很快就会创建所需的页面。

四、创建自定义顶栏

接下来创建一个新的"组件"包并创建文件CustomTopAppBar.kt并粘贴/输入以下代码:

kotlin 复制代码
package com.example.formexample.component

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.navigation.NavController

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CustomTopAppBar(navController: NavController, title: String, showBackIcon: Boolean) {
    TopAppBar(
        title = { Text(text = title) },
        navigationIcon = {
            if (showBackIcon && navController.previousBackStackEntry != null) {
                IconButton(onClick = { navController.navigateUp() }) {
                    Icon(
                        Icons.Filled.ArrowBack,
                        contentDescription = "Back"
                    )
                }
            }
        }
    )
}

在这里,我们基本上设置了应用程序顶部栏并设置标题,如果启用了showBackIcon,则会显示后退按钮,按下后用户可以返回到上衣屏幕。

五、创建页面

接下来创建一个新的pages包。 创建ForgotPassword.kt文件并粘贴/输入以下内容:

ini 复制代码
package com.example.formexample.pages

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.formexample.component.CustomTopAppBar

@Composable
fun ForgotPassword(navController: NavHostController) {
    Box(modifier = Modifier.fillMaxSize()) {
        Scaffold(
            topBar = { CustomTopAppBar(
                navController = navController,
                title = "Forgot Password",
                showBackIcon = true
            )},
            content = { it ->
                Column(
                    modifier = Modifier.padding(it),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    val username = remember {
                        mutableStateOf(TextFieldValue())
                    }
                    Text(
                        text = "Forgot Password",
                        style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive)
                    )

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

                    TextField(
                        label = { Text(text = "Username") },
                        value = username.value,
                        onValueChange = { username.value = it }
                    )
                    
                    Spacer(modifier = Modifier.height(15.dp))

                    Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
                        Button(
                            onClick = { },
                            shape = RoundedCornerShape(50.dp),
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(50.dp)
                        ) {
                            Text(text = "Forgot Password")
                        }
                    }
                }
            }
        )
    }
}

@Preview(showBackground = true)
@Composable
fun ForgotPasswordPreview() {
    val navController = rememberNavController()
    ForgotPassword(navController)
}

这里我们使用compose的ui元素创建一个简单的表单。使用精美的字体、供用户输入用户名的文本输入和可点击的圆形按钮。

接下来我们将创建登录表单,因此创建一个名为Login.kt的文件并输入/粘贴以下代码:

ini 复制代码
package com.example.formexample.pages

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.formexample.ui.theme.Purple80

@Composable
fun LoginPage(navController: NavHostController) {
    Box(modifier = Modifier.fillMaxSize()) {
        ClickableText(
            text = AnnotatedString("Signup Here"),
            modifier = Modifier
                .align(Alignment.Center)
                .padding(20.dp),
            onClick = {
                navController.navigate("signup")
            },
            style = TextStyle(
                fontSize = 14.sp,
                fontFamily = FontFamily.Default,
                textDecoration = TextDecoration.Underline,
                color = Purple80
            )
        )
    }
    Column(
        modifier = Modifier.padding(20.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
         val username = remember {
             mutableStateOf(TextFieldValue())
         }
        val password = remember {
            mutableStateOf(TextFieldValue())
        }

        Text(
            text = "Login",
            style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive)
        )

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

        TextField(
            label = { Text(text = "Username")},
            value = username.value,
            onValueChange = {username.value = it},
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
        )

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

        Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
            Button(
                onClick = {},
                shape = RoundedCornerShape(50.dp),
                modifier = Modifier
                    .fillMaxWidth()
                    .height(50.dp)
            ) {
                Text(text = "Login")
            }
        }

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

        ClickableText(
            text = AnnotatedString("Forgot Password?"),
            onClick = { navController.navigate("forgot-password") },
            style = TextStyle(
                fontSize = 15.sp,
                fontFamily = FontFamily.Default
            )
        )
    }
}

@Preview
@Composable
fun LoginPagePreview() {
    val navController = rememberNavController()
    LoginPage(navController = navController)
}

这将使用compose的ui元素提供一个基本的登录表单,它提供了一个供用户注册的链接,如果用户忘记了密码,它还提供另一个链接。

最后,我们将创建最终表单,创建SignUp.kt文件并粘贴/输入以下代码:

ini 复制代码
package com.example.formexample.pages

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.formexample.component.CustomTopAppBar

@Composable
fun SignUp(navController: NavHostController) {
    Scaffold(
        topBar = { CustomTopAppBar(
            navController = navController,
            title = "SignUp",
            showBackIcon = true)
        },
        content = { it ->
            Column(
                modifier = Modifier.padding(it),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                val username = remember {
                    mutableStateOf(TextFieldValue())
                }
                
                val password = remember {
                    mutableStateOf(TextFieldValue())
                }
                
                val passwordConfirm = remember {
                    mutableStateOf(TextFieldValue())
                }
                
                Text(
                   text = "SignUp", 
                    style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive)
                )
                
                Spacer(modifier = Modifier.height(15.dp))
                
                TextField(
                    label = { Text(text = "Username")},
                    value = username.value, 
                    onValueChange = { username.value = it}
                )
                
                Spacer(modifier = Modifier.height(15.dp))
                
                TextField(
                    label = { Text( text = "Password") },
                    value = password.value, 
                    onValueChange = { password.value = it},
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
                )
                
                Spacer(modifier = Modifier.height(15.dp))

                TextField(
                    label = {Text(text = "Password Confirmation")},
                    value = passwordConfirm.value, 
                    onValueChange =  { passwordConfirm.value = it },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
                )
                
                Spacer(modifier = Modifier.height(15.dp))

                Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
                    Button(
                        onClick = {},
                        shape = RoundedCornerShape(50.dp),
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(50.dp)
                    ) {
                        Text(text = "SignUp")
                    }
                }
            }
        }
    )
}

@Preview
@Composable
fun SignUpPreview() {
    val navController = rememberNavController()
    SignUp(navController = navController)
}

同样,没有什么太复杂的,这个表单包含用户名和密码/确认密码输入文本的字段。

接下来,我们终于可以检查用户界面和导航,启动模拟器/实际设备,你应该能够看到/导航一下屏幕:

忘记密码:

登录:

注册:

小结

在这里,我展示了如何使用Android Jetpack Commpose 创建简单的注册表单。

希望这对想要尝试Android Jetpack Compose的人有所帮助。

相关推荐
深海呐1 小时前
Android AlertDialog圆角背景不生效的问题
android
ljl_jiaLiang1 小时前
android10 系统定制:增加应用使用数据埋点,应用使用时长统计
android·系统定制
花花鱼1 小时前
android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。
android
落落落sss3 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
消失的旧时光-19435 小时前
kotlin的密封类
android·开发语言·kotlin
服装学院的IT男6 小时前
【Android 13源码分析】WindowContainer窗口层级-4-Layer树
android
CCTV果冻爽7 小时前
Android 源码集成可卸载 APP
android
码农明明7 小时前
Android源码分析:从源头分析View事件的传递
android·操作系统·源码阅读
秋月霜风8 小时前
mariadb主从配置步骤
android·adb·mariadb
Python私教9 小时前
Python ORM 框架 SQLModel 快速入门教程
android·java·python