有段时间没碰Android了,近日发现Android studio竟然默认推荐使用Kotlin+Materail3来设计安卓应用,于是上手尝试了一下。
比起以前单独写布局,然后再使用Java代码操纵UI来说,Jetpack Compose组件化设计确实方便快捷。只需要使用kotlin语言,添加代码即可添加UI,就像vue那样,贼方便!
这个页面就是狗哥使用Material3的组件做出来的页面,效果非常好,比我自己写xml布局好看太多了!
代码如下
复制
@Composable
fun ExpenditureContent(value:MutableState<String>,onClick:()->Unit) {
Column(modifier = Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
Row(modifier = Modifier
.fillMaxWidth()
.height(60.dp),
verticalAlignment = Alignment.CenterVertically
){
Row(modifier = Modifier.weight(0.3f).padding(start = 16.dp),
verticalAlignment = Alignment.CenterVertically){
IconButton(onClick = { /* Handle icon selection */ },
modifier = Modifier
.size(36.dp) // 设置按钮的大小
.background(color = Color(0xFFFE656A), shape = CircleShape) // 添加圆形背景
.padding(8.dp) // 为图标增加内边距,使其不贴边显示
) {
Icon(
Icons.Outlined.DeleteOutline,
contentDescription = null,
modifier = Modifier.size(36.dp)
)
}
Text(text = "生活用品", fontSize = 18.sp, fontWeight = FontWeight.Bold,
modifier = Modifier.padding(start = 12.dp))
}
// 禁用键盘
val keyboardController = LocalSoftwareKeyboardController.current
Text(text = if (value.value.isNotEmpty()){value.value}else{"0.00"},
fontWeight = FontWeight.Bold,
textAlign = TextAlign.End,
fontSize = 22.sp,
color = Color(0xFFF75458),
modifier = Modifier.padding(end = 16.dp))
}
// 分割线
Divider(
color = Color(0xFFF4F3F5), // 设置分割线颜色
thickness = 1.dp, // 设置分割线的粗细
modifier = Modifier.padding(vertical = 8.dp) // 设置分割线的上下间距
)
//常用分类
var selectcategory by remember { mutableStateOf("生活用品") }
Column(modifier = Modifier.fillMaxWidth()) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = "常用类别", fontSize = 16.sp,modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(start = 16.dp))
Row(verticalAlignment = Alignment.CenterVertically ){
Text(text = "全部", fontSize = 16.sp)
IconButton(onClick = {}) {
Icon(Icons.Outlined.ChevronRight, contentDescription = null)
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.weight(0.8f),
) {
val cylist= listOf("早餐","晚餐","午餐","饮料","生活用品","晚餐","午餐","水电燃气","早餐","晚餐","午餐","饮料")
val columnsPerRow = 4 // 每行显示的图标数
val rows = remember { cylist.chunked(columnsPerRow) }
rows.forEachIndexed { index, rowcates ->
Row( modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = 4.dp),
horizontalArrangement =Arrangement.SpaceEvenly) {
rowcates.forEachIndexed { index, cate ->
Box(
modifier = Modifier.weight(0.1f).padding(horizontal = 4.dp)
.border(
width = 1.dp,
color = if (selectcategory == cate) {Color(0xFF005CBA)} else {Color.Gray} , // 边框颜色
shape = RoundedCornerShape(8.dp) // 边框形状
)
.clickable(
onClick = {selectcategory = cate;onClick()},
indication = null, // Ensures no ripple effect
interactionSource = remember { MutableInteractionSource() } // Handles click interaction
),
contentAlignment = Alignment.Center
) {
Text(text = cate, fontSize = 14.sp,
modifier = Modifier.padding(top = 8.dp, bottom = 8.dp, start = 16.dp, end = 16.dp),
color = if (selectcategory == cate) {Color(0xFF005CBA)} else {Color.Gray}
)
}
}
}
}
}
}
}
//付款账户
Row {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = "付款账户", fontSize = 16.sp, fontWeight = FontWeight.Bold,modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(start = 16.dp))
Row(verticalAlignment = Alignment.CenterVertically ){
IconButton(onClick = {}) {
Icon(Icons.Outlined.MonetizationOn, contentDescription = null)
}
Text(text = "现金", fontSize = 16.sp, fontWeight = FontWeight.Bold,modifier = Modifier.padding(end = 16.dp))
}
}
}
// 分割线
Divider(
color = Color(0xFFF4F3F5), // 设置分割线颜色
thickness = 1.dp, // 设置分割线的粗细
modifier = Modifier.padding(vertical = 8.dp) // 设置分割线的上下间距
)
//备注
val hint = "备注" // 提示语
var bzValue by remember { mutableStateOf("") } // 存储输入的值
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.Transparent, shape = MaterialTheme.shapes.medium)
.padding(horizontal = 8.dp, vertical = 16.dp)
) {
BasicTextField(
value = bzValue,
onValueChange = { bzValue = it },
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
textStyle = TextStyle(fontSize = 16.sp, color = Color.Black),
modifier = Modifier.fillMaxWidth()
)
// 显示提示语,只有在输入为空时才显示
if (bzValue.isEmpty()) {
Text(
text = hint,
fontSize = 16.sp,
color = Color.Gray, // 设置提示语的颜色
modifier = Modifier
.align(Alignment.CenterStart)
.padding(start = 8.dp) // 设置提示语的内边距
)
}
}
// 分割线
Divider(
color = Color(0xFFF4F3F5), // 设置分割线颜色
thickness = 1.dp, // 设置分割线的粗细
modifier = Modifier.padding(vertical = 8.dp) // 设置分割线的上下间距
)
//底部
Row(
modifier = Modifier
.fillMaxWidth()
.horizontalScroll(rememberScrollState()) // 添加水平滚动
) {
val items = listOf("今天 周一", "19:46", "无标签", "无商家", "无优惠", "人民币")
items.forEach { item ->
Box(
modifier = Modifier
.height(36.dp)
.padding(horizontal = 8.dp, vertical = 4.dp)
.border(
width = 1.dp,
color = Color.Gray,
shape = RoundedCornerShape(16.dp)
),
contentAlignment = Alignment.Center
) {
Text(text = item, fontSize = 14.sp,
modifier = Modifier.background(Color(0xFFF4F3F5),shape = RoundedCornerShape(16.dp))
.padding(vertical = 4.dp, horizontal = 10.dp))
}
}
}
Row(
modifier = Modifier
.padding(top = 8.dp)
.fillMaxWidth()
.horizontalScroll(rememberScrollState()) // 添加水平滚动
) {
val items = listOf("非报销", "无退款", "已付款", "不计入收支", "不计入预算")
items.forEach { item ->
Box(
modifier = Modifier
.height(36.dp)
.padding(horizontal = 8.dp, vertical = 4.dp)
.border(
width = 1.dp,
color = Color.Gray,
shape = RoundedCornerShape(16.dp)
),
contentAlignment = Alignment.Center
) {
Text(text = item, fontSize = 14.sp,
modifier = Modifier.background(Color(0xFFF4F3F5),shape = RoundedCornerShape(16.dp))
.padding(vertical = 4.dp, horizontal = 10.dp))
}
}
}
}
}
@Composable
fun CategoryButton(category: String) {
Button(
onClick = { /* Handle category click */ },
shape = CircleShape,
modifier = Modifier.size(80.dp)
) {
Text(text = category, textAlign = TextAlign.Center, fontSize = 14.sp)
}
}
@Composable
fun NumberPad(onNumberInput: (String) -> Unit,onDeleteClick:()->Unit, onSaveClick: () -> Unit,onGJClick: ()->Unit) {
// 获取上下文
// 获取系统的触觉反馈机制
val hapticFeedback = LocalHapticFeedback.current
Column(modifier = Modifier.fillMaxWidth()) {
Row(modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically) {
(1..3).forEach {
Box(modifier = Modifier.fillMaxWidth().weight(1f)){
NumberButton(number = it.toString(), onClick = { onNumberInput(it.toString()) })
}
}
Box(modifier = Modifier.weight(1f)
.height(60.dp).clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
onDeleteClick()
},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() }
),
contentAlignment = Alignment.Center
){
Icon(
painter = painterResource(id = R.drawable.del),
contentDescription = null,
modifier = Modifier.size(32.dp)
)
}
}
Row(modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically) {
(4..6).forEach {
Box(modifier = Modifier.fillMaxWidth().weight(1f)) {
NumberButton(
number = it.toString(),
onClick = { onNumberInput(it.toString()) })
}
}
Row(
modifier = Modifier
.weight(1f)
.height(60.dp)
.clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() } // Handles click interaction
),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "保存再记",
textAlign = TextAlign.Center,
fontSize = 16.sp,
fontWeight = FontWeight.W500
)
}
}
Row(modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically) {
Column(modifier = Modifier.fillMaxWidth().weight(3f)) {
Row(modifier = Modifier.fillMaxWidth()) {
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
(7..9).forEach {
Box(modifier = Modifier.fillMaxWidth().weight(1f)) {
NumberButton(
number = it.toString(),
onClick = { onNumberInput(it.toString()) })
}
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.height(60.dp)
.fillMaxWidth()
.weight(1f)
.clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
onGJClick()
},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() } // Handles click interaction
),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(id = R.drawable.calculator),
contentDescription = null,
modifier = Modifier.size(32.dp)
)
}
Box(modifier = Modifier.fillMaxWidth().weight(1f)
.clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() } // Handles click interaction
),) {
NumberButton(number = "0",
onClick = { onNumberInput("0") })
}
Box(modifier = Modifier.fillMaxWidth().weight(1f)) {
NumberButton(number = ".", onClick = { onNumberInput(".") })
}
}
}
}
Box(modifier = Modifier
.weight(1f)
.height(120.dp)
.background(Color(0xFF005CBA))
.clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
onSaveClick()
},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() }
),
contentAlignment = Alignment.Center
) {
Text(
text = "保存",
fontSize = 18.sp,
color = Color.White
)
}
}
}
}
@Composable
fun NumberButton(number: String, onClick: () -> Unit) {
// 获取系统的触觉反馈机制
val hapticFeedback = LocalHapticFeedback.current
Box(
modifier = Modifier
.height(60.dp)
.fillMaxWidth()
.clickable(
onClick = {
// 触发系统级触觉反馈
hapticFeedback.performHapticFeedback(HapticFeedbackType.TextHandleMove)
onClick()},
indication = LocalIndication.current, // 启用默认的点击动画效果
interactionSource = remember { MutableInteractionSource() } // Handles click interaction
),
contentAlignment = Alignment.Center
) {
Text(text = number, fontSize = 24.sp, fontWeight = FontWeight.W500)
}
}
在组件前标注@Preview
即可预览,强烈建议大家试试。
评论 (0)