当前位置:网站首页>Jetpack Compose——Modifier的基本属性简单介绍

Jetpack Compose——Modifier的基本属性简单介绍

2022-08-09 13:12:00 lplj717

首先来看一个简单的例子:

    Column {
        Box(
            Modifier
                .size(100.dp)
                .background(Color.Green)
                .padding(16.dp)
        )
        Box(
            Modifier
                .size(100.dp)
                .padding(16.dp)
                .background(Color.Green)
        )
    

效果如图:

Modifier的设计中可以看出modifier的顺序不同会导致效果不同
如果先设置背景,然后设置padding,那么padding是在绿色背景的基础上进行的
如果是先设置padding,那么设置背景色是针对padding之后的布局进行设置

宽度,高度,边距(Size类)

size

size(size: Dp)//同时设置宽高
size(width: Dp, height: Dp)//设置宽高
size(size: DpSize)//设置宽高属性属性

 width:单独设置宽度

width(width: Dp)

 hegiht:单独设置高度

hegiht(hegiht: Dp)

defaultMinSize:设置默认宽高的最小值

defaultMinSize(
    minWidth: Dp = Dp.Unspecified,
    minHeight: Dp = Dp.Unspecified
)

sizeIn:设置宽高的最小值和最大值,宽度在minWidth~maxWidth之间,高度在minHeight~maxHeight之间

sizeIn(
    minWidth: Dp = Dp.Unspecified,
    minHeight: Dp = Dp.Unspecified,
    maxWidth: Dp = Dp.Unspecified,
    maxHeight: Dp = Dp.Unspecified
)

也有单独给宽度或高度设置的方法

widthIn(min: Dp = Dp.Unspecified, max: Dp = Dp.Unspecified)
heightIn(min: Dp = Dp.Unspecified, max: Dp = Dp.Unspecified)

fillMaxSize:宽高都填充满父布局(相当于原生xml中的match_parent),默认是1f,代表填充满父布局,如果设置为0.5f,则是填满父布局的0.5(即一半)

fillMaxSize(fraction: Float = 1f)

除此之外,也有单独给宽度或高度方法

fillMaxWidth(fraction: Float = 1f)
fillMaxHegiht(fraction: Float = 1f)

wrapContentSize:组件的控件宽高若是小与定义的最小宽高,会将组件进行排列的设置

    Column {
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .size(20.dp)//设置的size小于最小宽高,最终渲染出来的就是40*40的
                .background(Color.Blue)
        )
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentSize(Alignment.TopCenter)//设置wrapContentSize
                .size(20.dp)//设置的size小于最小宽高,最终渲染出来的就是20*20的,对齐方式为TopCenter
                .background(Color.Red)
        )
    }

效果如图:

 也有单独设置宽高的方法:

//设置宽度
wrapContentWidth(
    align: Alignment.Horizontal = Alignment.CenterHorizontally,
    unbounded: Boolean = false
)
//设置高度
wrapContentHeight(
    align: Alignment.Vertical = Alignment.CenterVertically,
    unbounded: Boolean = false
)
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentHeight(Alignment.CenterVertically)//设置wrapContentSize
                .height(20.dp)//高20,宽40,垂直居中
                .background(Color.Yellow)
        )
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentWidth(Alignment.CenterHorizontally)//设置wrapContentSize
                .width(20.dp)//宽20,高40,水平居中
                .background(Color.Green)
        )

如图:

综合:

Column {
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .size(20.dp)//设置的size小于最小宽高,最终渲染出来的就是40*40的
                .background(Color.Blue)
        )
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentSize(Alignment.TopCenter)//设置wrapContentSize
                .size(20.dp)//设置的size小于最小宽高,最终渲染出来的就是20*20的,对齐方式为TopCenter
                .background(Color.Red)
        )
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentHeight(Alignment.CenterVertically)//设置wrapContentSize
                .height(20.dp)//高20,宽40,垂直居中
                .background(Color.Yellow)
        )
        Box(
            Modifier
                .sizeIn(minWidth = 40.dp, minHeight = 40.dp)
                .wrapContentWidth(Alignment.CenterHorizontally)//设置wrapContentSize
                .width(20.dp)//宽20,高40,水平居中
                .background(Color.Green)
        )
    }

效果如图:

 padding:边距,可以直接去查看构造参数(有四种),这里不多做介绍了

padding(all: Dp)

padding(
    horizontal: Dp = 0.dp,
    vertical: Dp = 0.dp
)

padding(
    start: Dp = 0.dp,
    top: Dp = 0.dp,
    end: Dp = 0.dp,
    bottom: Dp = 0.dp
)

padding(paddingValues: PaddingValues)

点击 双击 长按(事件类)

clickable:点击事件(其中onClickLabel和role主要是为盲人设置的属性)

clickable(
    enabled: Boolean = true,//控制启用状态
    onClickLabel: String? = null,//可访问性标签  
    role: Role? = null,//用户界面元素的类型
    onClick: () -> Unit//点击回调
)
clickable(
    interactionSource: MutableInteractionSource,//判断按钮的点击状态
    indication: Indication?,//绘制水波纹或者点击高亮的效果
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onClick: () -> Unit
)

使用:

    Column {
        Text(
            text = "点击显示水波纹效果",
            modifier = Modifier
                .clickable(
                    interactionSource = interactionSourceM,
                    indication = rememberRipple()
                ) { }
                .padding(10.dp)
        )
        Spacer(modifier = Modifier.requiredHeight(10.dp))
        Text(
            text = "跟随上面点击出现水波纹", modifier = Modifier
                .indication(
                    interactionSourceM,
                    LocalIndication.current
                )
                .padding(10.dp)
        )
    }

效果如图:

combinedClickable是实验性的API随时可能删除

@ExperimentalFoundationApi
fun Modifier.combinedClickable(
    enabled: Boolean = true,
    onClickLabel: String? = null,
    role: Role? = null,
    onLongClickLabel: String? = null,
    onLongClick: (() -> Unit)? = null,
    onDoubleClick: (() -> Unit)? = null,
    onClick: () -> Unit
)

 使用:

        Box(
            Modifier
                .size(50.dp)
                .background(Color.Blue)
                .combinedClickable(
                    onLongClick = {
                        Toast
                            .makeText(context, "长按", Toast.LENGTH_SHORT)
                            .show()
                    },
                    onDoubleClick = {
                        Toast
                            .makeText(context, "双击", Toast.LENGTH_SHORT)
                            .show()
                    },
                    onClick = {
                        Toast
                            .makeText(context, "点击", Toast.LENGTH_SHORT)
                            .show()
                    })
        )

效果:

 shape(形状),border(边框),background(背景)

关于shape可以查看之前写的Button中有详细介绍,这里介绍一下border

border:

border(width: Dp, brush: Brush, shape: Shape)
border(border: BorderStroke, shape: Shape = RectangleShape)
border(width: Dp, color: Color, shape: Shape = RectangleShape)
        val gradientBrush = Brush.horizontalGradient(
            colors = listOf(Color.Red, Color.Blue, Color.Green),
            startX = 0.0f,
            endX = 350.0f,
            tileMode = TileMode.Repeated
        )
        Text(
            text = "我是测试边框",
            modifier = Modifier
                .border(width = 2.dp, brush = gradientBrush, shape = CircleShape)
                .padding(10.dp)
        )

效果如图:

 background:设置背景及背景形状

background(
    color: Color,
    shape: Shape = RectangleShape
)
background(
    brush: Brush,
    shape: Shape = RectangleShape,
    /*@FloatRange(from = 0.0, to = 1.0)*/
    alpha: Float = 1.0f
) 
        val colorList = arrayListOf(Color(0xFF25BC6B), Color(0xFFFFCA1C))
        Box(
            modifier = Modifier
                .width(220.dp)
                .height(60.dp)
                .background(
                    brush = Brush.horizontalGradient(colorList),
                    shape = RoundedCornerShape(50)
                )
                .padding(10.dp)

        )

效果如图:

滑动效果

Compose没有Scrollview,要想Row或Column实现滚动效果,就得使用modifier来实现,如果不加verticalScroll,Column是无法向下滚动的

verticalScroll

verticalScroll(
    state: ScrollState,//滚动状态
    enabled: Boolean = true,//是否启用通过触摸输入滚动  
    flingBehavior: FlingBehavior? = null,
    reverseScrolling: Boolean = false//false默认顶部,true自动滚动到底部
) 
    Column(Modifier.verticalScroll(rememberScrollState())) {
        repeat(10){
            Box(
                Modifier
                    .fillMaxWidth()
                    .height(200.dp)
            ){
                Text(text = "item:$it")
            }
        }
    }

效果如图:

Column + verticalScroll 实现垂直方向的滚动效果
Row + horizontalScroll  实现水平方向的滚动效果
horizontalScroll和verticalScroll参数和使用基本类似,这里不再重复记录

horizontalScroll(
    state: ScrollState,
    enabled: Boolean = true,
    flingBehavior: FlingBehavior? = null,
    reverseScrolling: Boolean = false
) 

scrollable:在单个方向中为UI元素配置触摸滚动和投掷

scrollable(
    state: ScrollableState,
    orientation: Orientation,
    enabled: Boolean = true,
    reverseDirection: Boolean = false,
    flingBehavior: FlingBehavior? = null,
    interactionSource: MutableInteractionSource? = null
)
val offset = remember { mutableStateOf(0f) }
    Box(
        Modifier
            .size(150.dp)
            .scrollable(
                orientation = Orientation.Vertical,
                // state for Scrollable, describes how consume scroll amount
                state = rememberScrollableState { delta ->
                    offset.value = offset.value + delta // update the state
                    delta // indicate that we consumed all the pixels available
                }
            )
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        Text(offset.value.roundToInt().toString(), style = TextStyle(fontSize = 32.sp))
    }

效果如图:

 selectable:实现单选功能

        val option1 = Color.Green
        val option2 = Color.Cyan
        var selectedOption by remember { mutableStateOf(option1) }
        Column {
            Text("Selected: $selectedOption")
            Row {
                listOf(option1, option2).forEach { color ->
                    val selected = selectedOption == color
                    Box(
                        Modifier
                            .size(140.dp)
                            .background(color = color)
                            .selectable(
                                selected = selected,
                                onClick = { selectedOption = color }
                            )
                    ) {
                        if (selected) Text(text = "已选", color = Color.White)
                    }
                }
            }
        }

效果如图:

toggleable类似复选框的勾选及不勾选

        var checked by remember { mutableStateOf(false) }
        Text(
            modifier = Modifier.toggleable(value = checked, onValueChange = { checked = it }),
            text = if(checked) "勾选" else "非勾选"
        )

效果如图:

 aspectRatio:纵横比

    Column {
        Box(
            Modifier
                .size(100.dp)
                .background(Color.Cyan)
        )
        Spacer(modifier = Modifier.requiredHeight(10.dp))
        Box(
            Modifier
                .width(100.dp)
                .aspectRatio(2f)
                .background(Color.Green)
        )
    }

效果如图:

 rotate:组件沿中心顺时针旋转,最高支持360°

        Box(
            Modifier
                .rotate(45f)
                .background(Color.Blue)
                .size(100.dp, 100.dp)
        )

 scale:缩放

        Box(
            Modifier
                .background(Color.Black)
                .size(100.dp, 100.dp)
        )
        Spacer(modifier = Modifier.requiredHeight(10.dp))
        Box(
            Modifier.scale(scaleX = 0.2f, scaleY = 0.5f)
                .background(Color.Black)
                .size(100.dp, 100.dp)
        )

效果如图:

持续奋斗。。。。

原网站

版权声明
本文为[lplj717]所创,转载请带上原文链接,感谢
https://blog.csdn.net/lplj717/article/details/121925809