Jetpack Compose(五)-按钮组件

一、Button按钮

(1)先看下Button的参数:

kotlin 复制代码
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Button(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,      //是否启用按钮
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },   //点击交互的效果
    elevation: ButtonElevation? = ButtonDefaults.elevation(),   //按钮的阴影
    shape: Shape = MaterialTheme.shapes.small,
    border: BorderStroke? = null,
    colors: ButtonColors = ButtonDefaults.buttonColors(),
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    content: @Composable RowScope.() -> Unit
) {...}

Button的第一个参数onClick是必填项,这是其最重要的功能,通过回调响应用户点击事件。最后一个参数content也是一个必填项,也是其最重要的功能之一。ComposeButton默认没有任何UI。仅仅是一个响应onClick的容器,它的UI需要在content中通过其他组件来实现。

ButtononClick在底层是通过覆盖Modifier.clickable实现的,所以不要为Button设置Modifier.clickable,即使设置了,也会因为被onClick覆盖而没有任何效果。

(2)创建一个显示文字的Button,代码如下:

kotlin 复制代码
@Composable
fun Greeting() {
    Button(onClick = {
        showToast("点击了按钮")
    }) {
        Text(text = "确定")
    }
}

content提供了RowScope的作用域,所以当我们想在文字前面水平摆放一个Icon时,只需要在content中顺序书写即可:

kotlin 复制代码
@Composable
fun Greeting() {
    Button(onClick = {
        showToast("点击了按钮")
    }) {
        Icon(imageVector = Icons.Filled.Done, contentDescription = null)
        Text(text = "确定")
    }
}

UI效果

(3)Button的参数interactionSourceButton有一个参数interactionSource,它是一个可以监听组件状态的事件源,通过它我们可以根据组件状态设置不同的样式,比如按钮按下时什么效果,正常时什么效果,类似传统视图中的SelectorinteractionSource通过以下方法获取当前组件状态:

  • interactionSource.collectIsPressedAsState()判断是否按下状态。
  • interactionSource.collectIsFocusedAsState()判断是否获取焦点的状态。
  • interactionSource.collectIsDraggedAsState()判断是否拖动。

来看下面的例子,通常状态下按钮背景色为灰色,当处于按下状态时,背景色变为黑色:

kotlin 复制代码
@Composable
fun Greeting() {
   val interactionSource = remember { MutableInteractionSource() }
   val pressState = interactionSource.collectIsPressedAsState()
   val backgroundColor = if (pressState.value) Color.Black else Color.Gray
   Button(
       onClick = {},
       interactionSource = interactionSource,
       colors = ButtonDefaults.buttonColors(backgroundColor = backgroundColor)
   ) {
       Text(text = "确定", color = Color.White)
   }
}

UI效果

Jetpack Compose博物馆中有一种写法可以借鉴:

①创建 Data class 来记录不同状态下按钮的样式

kotlin 复制代码
data class ButtonState(var text: String, var textColor: Color, var buttonColor: Color)

②使用 MutableInteractionSource() 获取状态,根据不同状态创建样式,代码如下:

kotlin 复制代码
@Composable
fun Greeting() {
    // 获取按钮的状态
    val interactionState = remember { MutableInteractionSource() }

    // 使用 Kotlin 的解构方法
    val (text, textColor, buttonColor) = when {
        interactionState.collectIsPressedAsState().value  -> ButtonState("Just Pressed", Color.Red, Color.Black)
        else -> ButtonState( "Just Button", Color.White, Color.Red)
    }

    Button(
        onClick = { /*TODO*/ },
        interactionSource = interactionState,
        elevation = null,
        shape = RoundedCornerShape(50),
        colors = ButtonDefaults.buttonColors(
            backgroundColor = buttonColor,      //buttonColor
        ),
        modifier = Modifier.width(IntrinsicSize.Min).height(IntrinsicSize.Min)
    ) {
        Text(
            text = text, color = textColor    //text,textColor
        )
    }
}

二、IconButton图标按钮

上一篇中的IconButton

三、FloatingActionButton(FAB)悬浮按钮

具体参数如下:

kotlin 复制代码
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
    backgroundColor: Color = MaterialTheme.colors.secondary,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    content: @Composable () -> Unit
) {...}

下面是一个简单的例子

kotlin 复制代码
@Composable
fun Greeting() {
    val isClick = remember {
        mutableStateOf(false)
    }
    //修改图标
    val imageVector = if (isClick.value) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder

    FloatingActionButton(
        onClick = { isClick.value = !isClick.value },
        backgroundColor = Color.White,
        contentColor = Color.Red
    ) {
        Icon(imageVector = imageVector, contentDescription = null)
    }
}

UI效果

除了普通的FAB之外,Compose也提供了带有文字扩展的FAB,即ExtendedFloatingActionButton组件,源码如下:

kotlin 复制代码
@Composable
fun ExtendedFloatingActionButton(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    icon: @Composable (() -> Unit)? = null,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
    backgroundColor: Color = MaterialTheme.colors.secondary,
    contentColor: Color = contentColorFor(backgroundColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()
) {...}

下面是一个简单的例子:

kotlin 复制代码
@Composable
fun Greeting() {
    ExtendedFloatingActionButton(
        text = { Text(text = "喜欢") },
        onClick = { },
        icon = { Icon(imageVector = Icons.Filled.Favorite, contentDescription = null) },
        contentColor = Color.Red
    )
}

UI效果

参考了以下内容

Jetpack Compose博物馆

实体书 Jetpack Compose从入门到实战

相关推荐
Zender Han10 小时前
Flutter 自适应(Adaptive)与响应式(Responsive)设计实践:官方推荐方案详解
android·flutter·ios
我命由我1234510 小时前
Android 开发问题:TopAppBar 和 topAppBarColors API is experimental...
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
造火箭11 小时前
Android UI自动化测试可行性评估SKILL
android·功能测试·ui
hunterandroid13 小时前
[Android 从零到一] ViewPager2 与 Fragment 生命周期协同:从预加载到状态一致性
android·前端
mmsx13 小时前
一个黑边 Bug 修了两版:自己算矩阵直接黑屏,借库重建只用了一行 setZoom
android·前端
枢影Kernel13 小时前
Android CLI 与 Android Skills 最佳实践:把 AI Agent 接入可验证的 Android 开发流程
android
Kapaseker14 小时前
没想到吧!Skill 也可以测试 — 小白都看得懂的 Skill 教程
android·人工智能·kotlin
我命由我1234514 小时前
Android 开发问题:使用 AndroidTreeView 时,自定义视图无法撑满父容器
android·java·java-ee·kotlin·android studio·android-studio·android runtime
没文化的阿浩14 小时前
【MySQL】数据类型
android·mysql·adb
恋猫de小郭15 小时前
社区版 Dart macros?一个可以解决 JSON 序列化的Fluter “宏编程”第三方包
android·前端·flutter