Jetpack Compose 基础组件之-Button、FloatingActionButton、Image

499 阅读2分钟

一:Button 1.构造方法

@Composable
fun Button(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
    shape: Shape = FilledButton.ContainerShape,
    border: BorderStroke? = null,
    colors: ButtonColors = ButtonDefaults.buttonColors(),
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    content: @Composable RowScope.() -> Unit
)
  • onClick 点击事件
  • modifier 背景、宽高等
  • enable 是否可点击
  • interactionSource 类似selector,状态有collectIsPressedAsState(是否按压)、collectIsFocusedAsState(是否有焦点)、collectIsDraggedAsState(是否拖动)、collectIsHoveredAsState(是否悬停)
举例:
val interactionState = remember { MutableInteractionSource() }
val shape = if (interactionState.collectIsPressedAsState().value ){
    RoundedCornerShape(33.dp)
}else{
    CutCornerShape(5.dp,8.dp,0.dp,6.dp)
}
Button(onClick = { },
    colors = ButtonDefaults.buttonColors(
        containerColor = Color.Black,
        contentColor = Color.White,
        disabledContainerColor = Color.Gray,
        disabledContentColor = Color.Blue,
    ),
    interactionSource = interactionState2,
    shape = shape,
)
也可以写一个data class,控制button其他属性
  • elevation 阴影,按钮默认没有阴影
@Composable
fun buttonElevation(
    defaultElevation: Dp = FilledButton.ContainerElevation,
    pressedElevation: Dp = FilledButton.PressedContainerElevation,
    focusedElevation: Dp = FilledButton.FocusContainerElevation,
    hoveredElevation: Dp = FilledButton.HoverContainerElevation,
    disabledElevation: Dp = FilledButton.DisabledContainerElevation,
)
  • shape 默认是 RoundedCornerShape(20.0.dp),默认实现了的有RoundedCornerShape 圆角形状,CutCornerShape 切角形状,AbsoluteRoundedCornerShape 绝对圆角形状,AbsoluteCutCornerShape 绝对切角形状 -border 边框 -colors 按钮颜色,可设置可点击时文本颜色、背景颜色,不可点击时文本颜色、背景颜色 -contentPadding 文本内边距,水平默认24,垂直8 -content 按钮内容,可设置文本、图片等

2.其他 button默认实现是有点击水波纹的,所以如果要去掉只能用不是material主题,或者复制按钮实现方法,indication = rememberRipple()改为 indication = null

Modifier.clickable(
    interactionSource = interactionSource,
    indication = rememberRipple(),
    enabled = true,
    onClickLabel = null,
    role = Role.Button,
    onClick = onClick
)

二:FloatingActionButton

1.构造方法

@Composable
fun FloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = FabPrimary.PrimaryContainerShape,
    containerColor: Color = MaterialTheme.colorScheme.fromToken(FabPrimary.PrimaryContainerColor),
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    content: @Composable () -> Unit,
)

还有可放置图片和文字的 ExtendedFloatingActionButton

@Composable
fun ExtendedFloatingActionButton(
    text: @Composable () -> Unit,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    icon: @Composable (() -> Unit)? = null,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = ExtendedFabPrimary.PrimaryContainerShape,
    containerColor: Color = MaterialTheme.colorScheme.fromToken(
        ExtendedFabPrimary.PrimaryContainerColor
    ),
    contentColor: Color = contentColorFor(containerColor),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
) {
    FloatingActionButton(
        modifier = modifier.sizeIn(
            minWidth = 80.dp,
            minHeight = ExtendedFabPrimary.PrimaryContainerHeight,
        ),
        onClick = onClick,
        interactionSource = interactionSource,
        shape = shape,
        containerColor = containerColor,
        contentColor = contentColor,
        elevation = elevation,
    ) {
        val startPadding = if (icon == null) {
            ExtendedFabTextPadding
        } else {
            ExtendedFabPrimary.PrimaryIconSize / 2
        }
        Row(
            modifier = Modifier.padding(
                start = startPadding,
                end = ExtendedFabTextPadding
            ),
            verticalAlignment = Alignment.CenterVertically
        ) {
            if (icon != null) {
                icon()
                Spacer(Modifier.width(ExtendedFabIconPadding))
            }
            ProvideTextStyle(
                value = MaterialTheme.typography.fromToken(ExtendedFabPrimary.PrimaryLabelTextFont),
                content = text,
            )
        }
    }
}

看内部实现可以看出,就是在FAB的基础上组合一下

三:Image

1.构造方法

@Composable
fun Image(
    painter: Painter,
    contentDescription: String?,
    modifier: Modifier = Modifier,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    alpha: Float = DefaultAlpha,
    colorFilter: ColorFilter? = null
) 
  • painter 图片数据
  • contentDescription 文本描述,在残障模式下触摸该图片会播放该文字,用来做图片说明,可为空
  • modifier
  • alignment 图片位置
  • contentScale 图片缩放模式
Crop:保持图片宽高比,居中裁剪 类似于ScaleType.CENTER_CROP
Fit:保持图片宽高比,充满控件小的那一边,类似于ScaleType.FIT_CENTER
FillHeight:高度充满 
FillWidth:宽度充满
Inside:保持图片宽高比缩小,如果图片宽高比控件小,保持不变
None:不做处理,直接展示
FillBounds:不保持图片宽高比,充满控件宽高
ColorFilter.lighting
ColorFilter.tint
ColorFilter.colorMatrix

2.加载图片 a.直接加载图片,不知道图片类型-painterResource

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description)
)

b.加载bitmap

Image(
    bitmap = ImageBitmap.imageResource(id = R.drawable.label_s),
    contentDescription = null
)

c.加载矢量图片

Image(
    imageVector = ImageVector.vectorResource(id = R.drawable.label_s),
    contentDescription = null
)

d.加载网络图片 1.使用coil

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = "Translated description of what the image contains"
)

2.使用glide

引入:
implementation "com.github.bumptech.glide:compose:1.0.0-alpha.1"

使用:
GlideImage(model = myUrl, contentDescription = getString(R.id.picture_of_cat))

GlideImage(
  model = myUrl,
  contentDescription = getString(R.id.picture_of_cat),
  modifier = Modifier.padding(padding).clickable(onClick = onClick).fillParentMaxSize(),
) {
   it
    .thumbnail(
      requestManager
      .asDrawable()
      .load(item.uri)
      .signature(signature)
      .override(THUMBNAIL_DIMENSION)
    )
    .signature(signature)
}