在 Android UI 技术不断演进的今天,Jetpack Compose 已经成为构建界面的主流方式。相比传统 XML,Compose 拥有更高的开发效率、响应式 UI 更新和更强的结构扩展能力,超级适合制作登录界面等表单交互页面。
本文分享一个现代化的登录界面实现示例,包括:
适合直接用于实际项目或进一步扩展。
界面演示示意:

@Composable
fun LoginScreen(
androidId: String,
defaultUsername: String,
defaultPassword: String,
isLoading: Boolean = false,
onLoginClick: (String, String) -> Unit
) {
var username by remember { mutableStateOf(defaultUsername) }
var password by remember { mutableStateOf(defaultPassword) }
var passwordVisible by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF5F5F5))
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 20.dp)
) {
Spacer(modifier = Modifier.height(50.dp))
Text(
text = "登陆",
fontSize = 30.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF333333)
)
Spacer(modifier = Modifier.height(30.dp))
Image(
painter = painterResource(id = R.mipmap.ic_admin_logo),
contentDescription = "Logo",
modifier = Modifier
.size(200.dp)
.align(Alignment.CenterHorizontally)
)
Spacer(modifier = Modifier.height(20.dp))
InputField(
value = username,
onValueChange = { username = it },
hint = "用户名"
)
Spacer(modifier = Modifier.height(20.dp))
InputField(
value = password,
onValueChange = { password = it },
hint = "密码",
isPassword = true,
passwordVisible = passwordVisible,
onPasswordToggleClick = { passwordVisible = !passwordVisible }
)
Spacer(modifier = Modifier.height(20.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.shadow(4.dp, RoundedCornerShape(12.dp))
.background(
brush = Brush.horizontalGradient(
listOf(Color(0xFF42A5F5), Color(0xFF1E88E5))
),
shape = RoundedCornerShape(12.dp)
)
.clickable { onLoginClick(username, password) },
contentAlignment = Alignment.Center
) {
Text(text = "登陆", fontSize = 18.sp, color = Color.White)
}
Spacer(modifier = Modifier.weight(1f))
Text(
text = androidId,
modifier = Modifier.fillMaxWidth().padding(10.dp),
fontSize = 10.sp,
textAlign = TextAlign.Center,
color = Color.Gray
)
}
AnimatedVisibility(visible = isLoading, enter = fadeIn(), exit = fadeOut()) {
Box(
modifier = Modifier.fillMaxSize().background(Color(0x66000000)),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator(color = Color(0xFF1E88E5))
}
}
}
}
@Composable
fun InputField(
value: String,
onValueChange: (String) -> Unit,
hint: String,
isPassword: Boolean = false,
passwordVisible: Boolean = false,
onPasswordToggleClick: (() -> Unit)? = null
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.shadow(2.dp, RoundedCornerShape(12.dp))
.background(Color.White, RoundedCornerShape(12.dp))
.padding(horizontal = 12.dp, vertical = 6.dp)
) {
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxSize(),
singleLine = true,
visualTransformation = if (isPassword && !passwordVisible)
PasswordVisualTransformation() else VisualTransformation.None,
textStyle = LocalTextStyle.current.copy(
color = Color(0xFF333333), fontSize = 16.sp
),
decorationBox = { inner ->
if (value.isEmpty()) {
Text(text = hint, color = Color.Gray, fontSize = 16.sp)
}
inner()
}
)
if (isPassword) {
Icon(
imageVector = if (passwordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff,
contentDescription = null,
tint = Color.Black,
modifier = Modifier
.align(Alignment.CenterEnd)
.clickable { onPasswordToggleClick?.invoke() }
)
}
}
}
这个登录界面完整展示了 Compose 在以下能力上的优势:
Compose 正在改变 Android UI 的构建方式,想要提升开发效率与界面表现,真的值得深入学习。