Compose 可组合项 - 一些交互类型

本文详细介绍了Flutter中的各种基础UI组件,包括Button的各种变体,如带有边框的OutlineButton和仅图标形状的IconButton;文本输入框TextField的功能,如样式、颜色和键盘选项;以及Slider、RangeSlider、CheckBox、RadioButton和Switch等组件的使用。

一、按钮 Button

OutLinedButton带外边框、TextButton只是文字、IconButton只是图标形状。

Button(
    onClick = { }, //点击回调
    modifier = Modifier,
    enabled = true, //启用或禁用
    interactionSource = MutableInteractionSource(),
    elevation = ButtonDefaults.elevatedButtonElevation( //高度(阴影)
        defaultElevation = 10.dp,   //启用时
        pressedElevation = 0.dp,   //按下时
        focusedElevation = 10.dp,
        hoveredElevation = 10.dp,
        disabledElevation = 10.dp   //未启用时
    ),
    shape = ButtonDefaults.shape,    //形状
    border = BorderStroke(width = 1.dp, color = Color.Red), //边框线
    colors = ButtonDefaults.buttonColors(   //颜色(还有textButtonColors、outlineButtonColors)
        containerColor = Color.Yellow,  //启用状态下的背景色
        contentColor = Color.Red,   //启动状态下的文本色
        disabledContainerColor = Color.Black,   //禁用状态下的背景色
        disabledContentColor = Color.Green  //禁用状态下的文本色
    ),
    contentPadding = ButtonDefaults.ContentPadding,    //内容内间距
) {
    //子元素
}

二、下拉菜单 DropdownMenu

本身不会占用布局中的空间,是在一个单独的窗口中显示的,在其他内容之上。

@Composable
fun DropdownMenu(
    expanded: Boolean,        //是否展开
    onDismissRequest: () -> Unit,        //关闭的回调
    modifier: Modifier = Modifier,
    offset: DpOffset = DpOffset(0.dp, 0.dp),        //偏移
    properties: PopupProperties = PopupProperties(

        focusable = true,        //是否聚焦

        dismissOnBackPress = true,        //是否响应返回键关闭弹窗

        dismissOnClickOutside = true,        //是否响应外部点击关闭弹窗

        securePolicy = SecureFlagPolicy.Inherit,    //是否可以被截屏(Inherit跟随父元素、SecureOn禁止、SecureOff允许)

),
    content: @Composable ColumnScope.() -> Unit        //菜单内容
)

 

var expandedState by remember { mutableStateOf(false) }
Column {
    Button(onClick = { expandedState = !expandedState }) {
        Text(text = "点击打开")
    }
    DropdownMenu(
        modifier = Modifier,
        expanded = expandedState,  //是否展开
        offset = DpOffset(10.dp, 10.dp),    //展开菜单的偏移量
        properties = PopupProperties(
            focusable = true,   //是否聚焦
            dismissOnBackPress = true,  //消失响应返回键
            dismissOnClickOutside = true,   //消失响应外围点击
            securePolicy = SecureFlagPolicy.SecureOn    //是否可以被截屏(Inherit跟随父元素、SecureOn禁止、SecureOff允许)
        ),
        onDismissRequest = {    //消失回调
            expandedState = false
        }
    ) {
        DropdownMenuItem(
            modifier = Modifier,
            text = { Text(text = "苹果") },
            leadingIcon = { Icon(imageVector = Icons.Default.Home, contentDescription = null) },   //左侧图标
            trailingIcon = { Icon(imageVector = Icons.Default.Email, contentDescription = null) },  //右侧图标
            enabled = true, //是否启用
            colors = MenuDefaults.itemColors(),
            contentPadding = PaddingValues(5.dp),
            onClick = { /*TODO*/ }  //点击事件
        )
        DropdownMenuItem(text = { Text(text = "桔子") }, onClick = {  })
        DropdownMenuItem(text = { Text(text = "香蕉") }, onClick = {  })
    }
}

三、弹窗 Popup

显示的时候,背景不会变暗,建议在 content 的根布局加个阴影。

@Composable
fun Popup(
    alignment: Alignment = Alignment.TopStart,
    offset: IntOffset = IntOffset(0, 0),        //偏移
    onDismissRequest: (() -> Unit)? = null,        //关闭回调

    properties: PopupProperties = PopupProperties(

        focusable = true,        //是否聚焦

        dismissOnBackPress = true,        //是否响应返回键关闭弹窗

        dismissOnClickOutside = true,        //是否响应外部点击关闭弹窗

        securePolicy = SecureFlagPolicy.Inherit,    //是否可以被截屏(Inherit跟随父元素、SecureOn禁止、SecureOff允许)

    content: @Composable () -> Unit        //弹窗内容
)
var showPopup by remember { mutableStateOf(false) }
if (showPopup) {
    Popup(
        alignment = Alignment.BottomEnd,
        offset = IntOffset(0, -70),
        onDismissRequest = { showPopup = false }
    ) {
        Column(
            modifier = Modifier
                .shadow(elevation = 10.dp, shape = RoundedCornerShape(AppDimens.radius))
                .background(color = AppColors.White, shape = RoundedCornerShape(AppDimens.radius))
        ) {
            Text(text = "条目1")
            Text(text = "条目2")
            Text(text = "条目3")
        }
    }
}

四、对话框 Dialog、AlertDialog

AlertDialog 属于 Material 风格,自定义选择 Dialog。

4.1 Dialog

var showDialog by remember { mutableStateOf(false) }
Column {
    Button(onClick = { showDialog = !showDialog }) {
        Text(text = "点击弹窗")
    }
    if (showDialog) {
        Dialog(
            onDismissRequest = { showDialog = false }, //消失回调
            properties = DialogProperties(
                dismissOnBackPress = true,  //消失响应返回键
                dismissOnClickOutside = true,   //消失响应外围点击
                securePolicy = SecureFlagPolicy.Inherit,    //是否可以被截屏(Inherit跟随父元素、SecureOn禁止、SecureOff允许)
                usePlatformDefaultWidth: Boolean = true,    //设为false不受固定最大宽度影响
                decorFitsSystemWindows: Boolean = true    //设为false不受固定最大高度影响
            )
        ) {
            Box(modifier = Modifier.size(100.dp).background(Color.Red))
        }
    }
}

4.2 AlertDialog

var showDialog by remember { mutableStateOf(false) }
Column {
    Button(onClick = { showDialog = !showDialog }) {
        Text(text = "点击弹窗")
    }
    if (showDialog) {
        AlertDialog(
            modifier = Modifier,
            //确认按钮
            confirmButton = { TextButton(onClick = { showDialog = false }) { Text(text = "确认") } },
            //取消按钮
            dismissButton = { TextButton(onClick = { showDialog = false }) { Text(text = "取消") } },
            //图标
            icon = { Icon(imageVector = Icons.Default.Home, contentDescription = null) },
            iconContentColor = Color.Magenta,
            //标题
            title = { Text(text = "标题") },
            titleContentColor = Color.Red,
            //内容
            text = { Text(text = "内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容") },
            textContentColor = Color.Blue,
            //背景
            shape = RoundedCornerShape(5.dp),
            containerColor = Color.Yellow,
            tonalElevation = 10.dp,
            //配置
            properties = DialogProperties(
                dismissOnBackPress = true,  //消失响应返回键
                dismissOnClickOutside = true,   //消失响应外围点击
                securePolicy = SecureFlagPolicy.Inherit,//是否可以被截屏(Inherit跟随父元素、SecureOn禁止、SecureOff允许)
            ),
            //消失回调
            onDismissRequest = {
                showDialog = false
            }
        )
    }
}

五、拖动条 Slider

var state by remember{ mutableStateOf(0.0F) }
Slider(
    value = state,   //当前值
    valueRange = 0F..100F,  //可选值范围(默认0F..1F)
    steps = 4,  //步频(默认0,设置了就中间只有这个值可选拖到)
    enabled = true, //是否禁用
    onValueChange = { float ->
        state = float
    }
)

 六、范围拖动条 RangeSlider

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Demo() {
    var state by remember{ mutableStateOf(5F..10F) }
    RangeSlider(
        value = state,  //注意值是一个范围
        valueRange = 0F..30F,   //可选值范围(默认0F..1F)
        steps = 3,  //步频(默认0,设置了就中间只有这个值可选拖到)
        onValueChange = {
            state = it
        }
    )
}

 七、复选框 CheckBox

fun Show() {
    val dataist = listOf("香菜", "酱油", "陈醋", "葱花", "蒜泥", "辣椒")
    Demo(dataist)
}

@Composable
fun Demo(list: List<String>) {
    //根据选项列表,创建相同数量的布尔值集合
    val state = remember { list.map { false }.toMutableStateList() }
    //根据选项列表,创建相同数量的复选框
    Column {
        state.forEachIndexed { index, value ->
            Row {
                Checkbox(
                    modifier = Modifier,
                    checked = value,    //是否选中
                    enabled = true, //是否启用
                    colors = CheckboxDefaults.colors(
                        checkedColor = AppColors.Primary,    //选中的填充色
                        uncheckedColor = AppColors.Hint,    //未选中的边框色
                        checkmarkColor = AppColors.White    //选中勾勾的颜色
                    ),
                    onCheckedChange = { boolean ->    //点击回调
                        state[index] = boolean
                    }
                )
                Text(text = list[index], modifier = Modifier.align(Alignment.CenterVertically))
            }
        }
    }
    //log检查是否被改动
    val str = StringBuilder().apply {
        state.onEach { append("$it、")}
    }
    Log.e("-----------",  str.toString())
}

 八、单选框 RadioButton

@Preview(showBackground = true)
@Composable
fun Show() {
    val dataist = listOf("香菜", "酱油", "陈醋", "葱花", "蒜泥", "辣椒")
    Demo(dataist)
}

@Composable
fun Demo(list: List<String>) {
    //记录当前被点击的索引(默认值设为0默认选中第一个,设为-1默认都不选中)
    var selectedIndex by remember { mutableStateOf(-1) }
    //根据选项列表,创建相同数量的单选框
    Column {
        list.forEachIndexed { index, _ ->
            Row {
                RadioButton(
                    modifier = Modifier,
                    selected = selectedIndex == index,   //是否选中
                    enabled = true, //是否启用
                    colors = RadioButtonDefaults.colors(),
                    onClick = {
                        selectedIndex = index
                        Log.e("-----------",  "点击的是第${index}个${list[index]}")
                    }
                )
                Text(text = list[index], modifier = Modifier.align(Alignment.CenterVertically))
            }
        }
    }
}

 九、开关 Switch

var state by remember { mutableStateOf(false) }
Switch(
    checked = state,    //控制开关
    onCheckedChange = { boolean ->  //点击事件
        state = boolean  //当进行切换操作时,更改状态
    },
    modifier = Modifier,
    thumbContent = null,
    enabled = true, //禁用(视觉和事件)
    colors = SwitchDefaults.colors(),   //不同状态下使用的颜色
//        interactionSource //可自定义不同状态下的外观和行为
)

十、徽章(小红点) BadgedBox

@Composable
fun BadgedBox(
    badge: @Composable BoxScope.() -> Unit,        //传入 Badge()
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit,        //在什么控件上显示
)
@Composable
fun Badge(
    modifier: Modifier = Modifier,
    containerColor: Color = BadgeDefaults.containerColor,        //小圆点颜色
    contentColor: Color = contentColorFor(containerColor),        //小圆点里的内容颜色
    content: @Composable (RowScope.() -> Unit)? = null,        //小圆点里的内容
)
@Composable
fun DemoScreen() {
    var itemCount by remember { mutableIntStateOf(0) }
    BadgedBox(
        badge = {
            //数量大于0才显示小圆点
            if (itemCount > 0) {
                Badge(
                    containerColor = AppColors.red, //小圆点颜色
                    contentColor = AppColors.white  //内容颜色
                ){
                    Text("$itemCount")  //小圆点里的内容
                }
            }
        }
    ) {
        //Icon、Image、Button或任意可组合项
    }
}

十一、悬浮按钮

一共四种:正常、小、大、展开。

正常@Composable
fun FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    shape: Shape = FloatingActionButtonDefaults.shape,        //形状
    containerColor: Color = FloatingActionButtonDefaults.containerColor,        //背景色
    contentColor: Color = contentColorFor(containerColor),        //内容色
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),        //阴影
    interactionSource: MutableInteractionSource? = null,
    content: @Composable () -> Unit,
)
SmallFloatingActionButton        //同上
LargeFloatingActionButton        //同上
展开fun ExtendedFloatingActionButton(
    text: @Composable () -> Unit,        //文字
    icon: @Composable () -> Unit,        //图标
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    expanded: Boolean = true,
    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,
    containerColor: Color = FloatingActionButtonDefaults.containerColor,
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    interactionSource: MutableInteractionSource? = null,
)

 

//正常
@Composable
fun Example(onClick: () -> Unit) {
    FloatingActionButton(
        onClick = { onClick() },
    ) {
        Icon(Icons.Filled.Add, "Floating action button.")
    }
}
//展开
@Composable
fun ExtendedExample(onClick: () -> Unit) {
    ExtendedFloatingActionButton(
        onClick = { onClick() },
        icon = { Icon(Icons.Filled.Edit, "Extended floating action button.") },
        text = { Text(text = "Extended FAB") },
    )
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值