Kotlin jetpack compose Tab的渲染 AnimatedVisibility的使用

Posted 安果移不动

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin jetpack compose Tab的渲染 AnimatedVisibility的使用相关的知识,希望对你有一定的参考价值。

​​​​​​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)
                )
            
        

    

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

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

以上是关于Kotlin jetpack compose Tab的渲染 AnimatedVisibility的使用的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin Jetpack Compose remember 给Icon添加透明度

Kotlin jetpack compose Tab的渲染 AnimatedVisibility的使用

Kotlin jetpack compose 文本输入框ExitText/TextField remember 居然可以传两个参数

Jetpack Compose开源:基于Kotlin的响应式编程方案,简化UI开发

Android Kotlin Jetpack Compose UI框架 完全解析

这个 kotlin jetpack compose 代码示例中的“提供”语法是啥?