当前位置:网站首页>Kotlin Compose 完善toDo项目 Surface 渲染背景 与阴影
Kotlin Compose 完善toDo项目 Surface 渲染背景 与阴影
2022-06-25 04:01:00 【安果移不动】
我们的todo 只能添加随机的todo 非常的不智能。下面来完善他。让他支持到可以进行添加自定义的项目
这里的阴影还没开始使用。
TodoComponents.kt
package com.anguomob.jecpack.activity.compose.todo.one
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.*
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.anguomob.jecpack.activity.compose.todo.bean.ToDoIcon
import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
@Composable
fun ToDoItemInputBackground(
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit,
elevatioon: Boolean
) {
//帧动画形式展示Surface底部的阴影
val animatedElevation by animateDpAsState(
targetValue = if (elevatioon) 1.dp else 0.dp,
TweenSpec(300)
)
Surface(
color = MaterialTheme.colors.onSurface.copy(alpha = 0.05f),
shape = RectangleShape,
elevation = animatedElevation
) {
Row(modifier = modifier.animateContentSize(animationSpec = TweenSpec(300))) {
content()
}
}
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun TodoInputText(
text: String,
onTextChanged: (String) -> Unit,
onImeAction: () -> Unit,
modifier: Modifier = Modifier,
) {
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
value = text,
onValueChange = onTextChanged,
modifier = modifier,
colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
maxLines = 1,
//配置软键盘
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {
onImeAction()
//点击完成之后 隐藏键盘
keyboardController?.hide()
})
)
}
@Composable()
fun TodoEditButton(
onClick: () -> Unit,
text: String,
modifier: Modifier = Modifier,
enable: Boolean = true
) {
TextButton(
onClick = onClick,
shape = CircleShape,
colors = ButtonDefaults.buttonColors(),
modifier = modifier,
enabled = enable
) {
Text(text)
}
}
@Composable
fun TodoItemEntryInput(onItemComplete: (TodoItem) -> Unit) {
val (text, setText) = remember {
mutableStateOf("")
}
val (icon, setIcon) = remember {
mutableStateOf(ToDoIcon.Default)
}
//icon是否可一件取决于文本是否有内容
val iconsVisible = text.isNotBlank()
//点击add
val submit = {
onItemComplete(TodoItem(text, icon))
setText("")
setIcon(ToDoIcon.Default)
}
TodoItemInput(
text = text,
onTextChange = setText,
icon = icon,
onIconChange = setIcon,
iconsVisible = iconsVisible,
submit = submit,
)
}
@Composable
fun TodoItemInput(
text: String,
onTextChange: (String) -> Unit,
icon: ToDoIcon,
onIconChange: (ToDoIcon) -> Unit,
iconsVisible: Boolean,
submit: () -> Unit
) {
Column {
Row(
Modifier
.padding(horizontal = 16.dp)
.padding(top = 16.dp)
) {
TodoInputText(
text = text,
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
onTextChanged = onTextChange,
onImeAction = submit
)
TodoEditButton(
onClick = submit,
text = "Add",
modifier = Modifier.align(Alignment.CenterVertically),
enable = text.isNotBlank()
)
}
AnimatedIconRow(
visible = iconsVisible,
icon = icon,
onIconChange = onIconChange,
modifier = Modifier.padding(8.dp)
)
}
}
//一排图标 根据文本框是否有内容 自动弹起收缩
@Composable
fun AnimatedIconRow(
modifier: Modifier = Modifier,
visible: Boolean,
icon: ToDoIcon,
onIconChange: (ToDoIcon) -> Unit
) {
val enter = remember {
fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
}
val exit = remember {
fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
}
//最小高度16dp
AnimatedVisibility(visible = visible, enter = enter, exit = exit, modifier = modifier) {
IconRow(icon = icon, onIconChange = onIconChange)
}
}
@Composable
fun IconRow(icon: ToDoIcon, onIconChange: (ToDoIcon) -> Unit, modifier: Modifier = Modifier) {
Row(modifier = modifier) {
for (todoIcon in ToDoIcon.values()) {
SelectableIconButton(
icon = todoIcon.imageVector,
iconContentDescription = todoIcon.contentDescription,
onIconSelect = { onIconChange(todoIcon) },
isSelected = todoIcon == icon
)
}
}
}
@Composable
fun SelectableIconButton(
icon: ImageVector,
iconContentDescription: Int,
onIconSelect: () -> Unit,
isSelected: Boolean,
modifier: Modifier = Modifier
) {
//图标选中和未选中 颜色不一样
val tint = if (isSelected) {
MaterialTheme.colors.primary
} else {
MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
}
val enter = remember {
fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
}
val exit = remember {
fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
}
TextButton(onClick = onIconSelect, modifier = modifier) {
Column {
Icon(
imageVector = icon,
tint = tint,
contentDescription = stringResource(id = iconContentDescription)
)
//最小高度16dp
AnimatedVisibility(visible = isSelected, enter = enter, exit = exit) {
Box(
Modifier
.padding(top = 3.dp)
.width(icon.defaultWidth)
.height(1.dp)
.background(tint)
)
}
}
}
}
TodoScreen.kt
package com.anguomob.jecpack.activity.compose.todo.one
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import com.anguomob.jecpack.R
import com.anguomob.jecpack.activity.compose.todo.bean.ToDoIcon
import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
import com.anguomob.jecpack.activity.compose.todo.viewmodel.TodoViewModel
import generateRandomTodoItem
import java.util.*
import kotlin.random.Random
@Composable
fun TodoActivityScreen(todoViewModel: TodoViewModel ) {
// val items = listOf(
// TodoItem("Learn compose", ToDoIcon.Event),
// TodoItem("Take a CodeLab"),
// TodoItem("Apply state", ToDoIcon.Done),
// odoItem("Build dynamic UIs", ToDoIcon.Square),
val items: List<TodoItem> by todoViewModel.todoItems.observeAsState(listOf())
TodoScreen(items = items, onAddItem = {
todoViewModel.addItem(it)
}, onItemClick = {
todoViewModel.removeItem(it)
})
}
@Composable
fun TodoScreen(
items: List<TodoItem>,
onAddItem: (TodoItem) -> Unit,
onItemClick: (TodoItem) -> Unit
) {
Column() {
//输入框 外加一个灰色背景
ToDoItemInputBackground(content = {
TodoItemEntryInput(onItemComplete = onAddItem)
}, elevatioon = true)
LazyColumn(
modifier = Modifier
.weight(1f)
) {
items(items) {
TodoRow(it, modifier = Modifier.fillParentMaxWidth(), onItemClick = onItemClick)
}
}
Button(
onClick = {
onAddItem(generateRandomTodoItem())
},
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Text("新建TODO")
}
}
}
@Composable
fun TodoRow(todo: TodoItem, modifier: Modifier = Modifier, onItemClick: (TodoItem) -> Unit) {
Row(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.clickable { onItemClick(todo) },
//子元素水平均匀分发
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(todo.task)
val iconAlpha = remember(todo.id) {
randomTint()
}
Icon(
imageVector = todo.icon.imageVector,
tint = LocalContentColor.current.copy(alpha = iconAlpha),
contentDescription = stringResource(id = todo.icon.contentDescription)
)
}
}
private fun randomTint(): Float {
val number = Random.nextFloat().coerceIn(0.3f, 0.9f)
return number
}数据bean等类容在这里
Kotlin Compose Todo小项目 删除添加项目 ,认识状态提升_安果移不动的博客-CSDN博客
效果就是通过点击

add之后可以选择图标和文案来进行写todo项目
关于阴影 可以重点关注这个

边栏推荐
- LabVIEW development gas regulator
- 第二十五周记录
- Deep learning - several types of learning
- 什么是数据持久化?
- Gbase 8s memory management
- Trigger for gbase 8s
- 《牛客刷verilog》Part I Verilog快速入门
- Gbase 8s index b+ tree
- [esp32 learning path 6 - Flash encryption]
- CTF_ Web: deserialization learning notes (I) classes and objects in PHP
猜你喜欢

关于TCP连接四次握手(或者叫四次挥手)的详细总结

Unity Quad culls shaders with back faces and transparent parts

GBASE 8s 索引B+树

PHP extracts and analyzes table contents, and collects bidding information

Bingbing's learning notes: implementation of circular queue

JS' sort() function

第九章 APP项目测试(2) 测试工具

js中的concat()

Join() in JSZ

cnpm : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。
随机推荐
Record small knowledge points
PostgreSQL数据库WAL——RM_HEAP_ID日志记录动作
微信小程序父子组件之间传值
GBase 8s的封锁技术的基本介绍
English Grammar - pronunciation rules
leetcode1221. 分割平衡字符串
Deep learning - several types of learning
Office macro virus bounce shell experiment
What is persistence? What are RDB and AOF in redis persistence?
Code scanning payment flow chart of Alipay payment function developed by PHP
Retrofit source code analysis
我的IC之旅——资深芯片设计验证工程师成长——“胡”说IC工程师完美进阶
坐标系左乘右乘
cnpm : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。
Upgrade PHP to php7 The impact of X (2), the obsolescence of mcrypt decryption
2021.8.29 notes: register, bit operation, pointer, structure
js的call()和apply()
JS call() and apply()
CTF_ Web: Advanced questions of attack and defense world expert zone WP (15-18)
GBASE 8s存储过程流程控制