Kotlin jetpack compose 文本输入框ExitText/TextField remember 居然可以传两个参数_安果移不动的博客-CSDN博客
接上篇博客
这节课实现
当有内容就动画出现下方tab
并且下方tab可以选择 切换
修改文件为
- package com.anguomob.jecpack.activity.compose.todo.one
-
- import androidx.compose.animation.AnimatedVisibility
- import androidx.compose.animation.core.FastOutLinearInEasing
- import androidx.compose.animation.core.FastOutSlowInEasing
- import androidx.compose.animation.core.TweenSpec
- 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.material.*
- 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.graphics.Color
- import androidx.compose.ui.graphics.vector.ImageVector
- import androidx.compose.ui.res.stringResource
- 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 TodoInputText(text: String, onTextChanged: (String) -> Unit, modifier: Modifier = Modifier) {
- TextField(
- value = text,
- onValueChange = onTextChanged,
- modifier = modifier,
- colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
- maxLines = 1,
- )
- }
-
- @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 TodoItemInput(onItemComplete: (TodoItem) -> Unit) {
- val (text, setText) = remember {
- mutableStateOf("")
- }
-
- val (icon, setIcon) = remember {
- mutableStateOf(ToDoIcon.Default)
- }
- //icon是否可一件取决于文本是否有内容
- val iconsVisible = text.isNotBlank()
-
- Column {
- Row(
- Modifier
- .padding(horizontal = 16.dp)
- .padding(top = 16.dp)
- ) {
-
- TodoInputText(
- text = text,
- modifier = Modifier
- .weight(1f)
- .padding(end = 8.dp),
- onTextChanged = setText
-
- )
- TodoEditButton(
- onClick = {
- onItemComplete(TodoItem(text))
- setText("")
- },
- text = "Add",
- modifier = Modifier.align(Alignment.CenterVertically),
- enable = text.isNotBlank()
- )
-
- }
- AnimatedIconRow(
- visible = iconsVisible,
- icon = icon,
- onIconChange = setIcon,
- 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)
- }
- TextButton(onClick = onIconSelect, shape = CircleShape, modifier = modifier) {
- Column {
- Icon(
- imageVector = icon,
- tint = tint,
- contentDescription = stringResource(id = iconContentDescription)
- )
- if (isSelected) {
- Box(
- Modifier
- .padding(top = 3.dp)
- .width(icon.defaultWidth)
- .height(1.dp)
- .background(tint)
- )
- } else {
- Spacer(modifier = Modifier.height(4.dp))
- }
- }
-
- }
- }
拆解下用到了那些东西
新增一个状态。其包含默认的icon图标还有选中状态
这是状态提升里面用用到的哦。
这个方法里面主要是两个动画 动画里面呢包含系统组件
AnimatedVisibility
又包含了自定义的一个组件
IconRow
我们继续看下这个
IconRow
组件
对枚举类型进行遍历并将遍历后的循环给到一个新的组件
我们看下这个新的组件
他其实是一个textButton
还加了shape。兄弟们说有没有必要加shape啊 其实没有的 所以可以删掉
然后这里针对是否选中做了针对底部下划线的隐藏处理
那兄弟们刚学完动画 是不是可以整活啊
可以的
- @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)
- )
- }
- }
-
- }
- }
这样每次点击的时候都有回馈 用户或许会更喜欢
当然后续学到了厉害的动画可以再来进行优化