• Kotlin jetpack compose Tab的渲染 AnimatedVisibility的使用


    ​​​​​​Kotlin jetpack compose 文本输入框ExitText/TextField remember 居然可以传两个参数_安果移不动的博客-CSDN博客

    接上篇博客

    这节课实现

    当有内容就动画出现下方tab

    并且下方tab可以选择 切换

     修改文件为

    1. package com.anguomob.jecpack.activity.compose.todo.one
    2. import androidx.compose.animation.AnimatedVisibility
    3. import androidx.compose.animation.core.FastOutLinearInEasing
    4. import androidx.compose.animation.core.FastOutSlowInEasing
    5. import androidx.compose.animation.core.TweenSpec
    6. import androidx.compose.animation.fadeIn
    7. import androidx.compose.animation.fadeOut
    8. import androidx.compose.foundation.background
    9. import androidx.compose.foundation.layout.*
    10. import androidx.compose.foundation.shape.CircleShape
    11. import androidx.compose.material.*
    12. import androidx.compose.runtime.Composable
    13. import androidx.compose.runtime.mutableStateOf
    14. import androidx.compose.runtime.remember
    15. import androidx.compose.ui.Alignment
    16. import androidx.compose.ui.Modifier
    17. import androidx.compose.ui.graphics.Color
    18. import androidx.compose.ui.graphics.vector.ImageVector
    19. import androidx.compose.ui.res.stringResource
    20. import androidx.compose.ui.unit.dp
    21. import com.anguomob.jecpack.activity.compose.todo.bean.ToDoIcon
    22. import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
    23. @Composable
    24. fun TodoInputText(text: String, onTextChanged: (String) -> Unit, modifier: Modifier = Modifier) {
    25. TextField(
    26. value = text,
    27. onValueChange = onTextChanged,
    28. modifier = modifier,
    29. colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
    30. maxLines = 1,
    31. )
    32. }
    33. @Composable()
    34. fun TodoEditButton(
    35. onClick: () -> Unit,
    36. text: String,
    37. modifier: Modifier = Modifier,
    38. enable: Boolean = true
    39. ) {
    40. TextButton(
    41. onClick = onClick,
    42. shape = CircleShape,
    43. colors = ButtonDefaults.buttonColors(),
    44. modifier = modifier,
    45. enabled = enable
    46. ) {
    47. Text(text)
    48. }
    49. }
    50. @Composable
    51. fun TodoItemInput(onItemComplete: (TodoItem) -> Unit) {
    52. val (text, setText) = remember {
    53. mutableStateOf("")
    54. }
    55. val (icon, setIcon) = remember {
    56. mutableStateOf(ToDoIcon.Default)
    57. }
    58. //icon是否可一件取决于文本是否有内容
    59. val iconsVisible = text.isNotBlank()
    60. Column {
    61. Row(
    62. Modifier
    63. .padding(horizontal = 16.dp)
    64. .padding(top = 16.dp)
    65. ) {
    66. TodoInputText(
    67. text = text,
    68. modifier = Modifier
    69. .weight(1f)
    70. .padding(end = 8.dp),
    71. onTextChanged = setText
    72. )
    73. TodoEditButton(
    74. onClick = {
    75. onItemComplete(TodoItem(text))
    76. setText("")
    77. },
    78. text = "Add",
    79. modifier = Modifier.align(Alignment.CenterVertically),
    80. enable = text.isNotBlank()
    81. )
    82. }
    83. AnimatedIconRow(
    84. visible = iconsVisible,
    85. icon = icon,
    86. onIconChange = setIcon,
    87. modifier = Modifier.padding(8.dp)
    88. )
    89. }
    90. }
    91. //一排图标 根据文本框是否有内容 自动弹起收缩
    92. @Composable
    93. fun AnimatedIconRow(
    94. modifier: Modifier = Modifier,
    95. visible: Boolean,
    96. icon: ToDoIcon,
    97. onIconChange: (ToDoIcon) -> Unit
    98. ) {
    99. val enter = remember {
    100. fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
    101. }
    102. val exit = remember {
    103. fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
    104. }
    105. //最小高度16dp
    106. AnimatedVisibility(visible = visible, enter = enter, exit = exit, modifier = modifier) {
    107. IconRow(icon = icon, onIconChange = onIconChange)
    108. }
    109. }
    110. @Composable
    111. fun IconRow(icon: ToDoIcon, onIconChange: (ToDoIcon) -> Unit, modifier: Modifier = Modifier) {
    112. Row(modifier = modifier) {
    113. for (todoIcon in ToDoIcon.values()) {
    114. SelectableIconButton(
    115. icon = todoIcon.imageVector,
    116. iconContentDescription = todoIcon.contentDescription,
    117. onIconSelect = { onIconChange(todoIcon) },
    118. isSelected = todoIcon == icon
    119. )
    120. }
    121. }
    122. }
    123. @Composable
    124. fun SelectableIconButton(
    125. icon: ImageVector,
    126. iconContentDescription: Int,
    127. onIconSelect: () -> Unit,
    128. isSelected: Boolean,
    129. modifier: Modifier = Modifier
    130. ) {
    131. //图标选中和未选中 颜色不一样
    132. val tint = if (isSelected) {
    133. MaterialTheme.colors.primary
    134. } else {
    135. MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
    136. }
    137. TextButton(onClick = onIconSelect, shape = CircleShape, modifier = modifier) {
    138. Column {
    139. Icon(
    140. imageVector = icon,
    141. tint = tint,
    142. contentDescription = stringResource(id = iconContentDescription)
    143. )
    144. if (isSelected) {
    145. Box(
    146. Modifier
    147. .padding(top = 3.dp)
    148. .width(icon.defaultWidth)
    149. .height(1.dp)
    150. .background(tint)
    151. )
    152. } else {
    153. Spacer(modifier = Modifier.height(4.dp))
    154. }
    155. }
    156. }
    157. }

    拆解下用到了那些东西

     新增一个状态。其包含默认的icon图标还有选中状态

    这是状态提升里面用用到的哦。

     

    这个方法里面主要是两个动画 动画里面呢包含系统组件

    AnimatedVisibility

     又包含了自定义的一个组件 

    IconRow

    我们继续看下这个

    IconRow

    组件

    对枚举类型进行遍历并将遍历后的循环给到一个新的组件

    我们看下这个新的组件

     

     他其实是一个textButton

    还加了shape。兄弟们说有没有必要加shape啊 其实没有的 所以可以删掉

    然后这里针对是否选中做了针对底部下划线的隐藏处理

    那兄弟们刚学完动画 是不是可以整活啊

    可以的

    1. @Composable
    2. fun SelectableIconButton(
    3. icon: ImageVector,
    4. iconContentDescription: Int,
    5. onIconSelect: () -> Unit,
    6. isSelected: Boolean,
    7. modifier: Modifier = Modifier
    8. ) {
    9. //图标选中和未选中 颜色不一样
    10. val tint = if (isSelected) {
    11. MaterialTheme.colors.primary
    12. } else {
    13. MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
    14. }
    15. val enter = remember {
    16. fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
    17. }
    18. val exit = remember {
    19. fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
    20. }
    21. TextButton(onClick = onIconSelect, modifier = modifier) {
    22. Column {
    23. Icon(
    24. imageVector = icon,
    25. tint = tint,
    26. contentDescription = stringResource(id = iconContentDescription)
    27. )
    28. //最小高度16dp
    29. AnimatedVisibility(visible = isSelected, enter = enter, exit = exit) {
    30. Box(
    31. Modifier
    32. .padding(top = 3.dp)
    33. .width(icon.defaultWidth)
    34. .height(1.dp)
    35. .background(tint)
    36. )
    37. }
    38. }
    39. }
    40. }

    这样每次点击的时候都有回馈 用户或许会更喜欢

    当然后续学到了厉害的动画可以再来进行优化

  • 相关阅读:
    Linux下为网卡分配IP的工具dhclient
    开源日报 0822 | 语音识别与推理
    ARM接口编程—UART(exynos 4412平台)
    程序员的数学课开篇词 数学,编程能力的营养根基
    向毕业妥协系列之机器学习笔记:构建ML系统(四)
    扬帆际海—shopee跨境店和本土店谁更有优势?
    sklearn快速入门教程:标准化
    Scala (十二) --------- IDEA 快捷键
    【数据库】数据库连接池导致系统吞吐量上不去-复盘
    【C++】智能指针
  • 原文地址:https://blog.csdn.net/mp624183768/article/details/125419795