Jetpack Compose学习(6)——关于Modifier的妙用
原文: Jetpack Compose学习(6)——关于Modifier的妙用 | Stars-One的杂货小窝
之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲解下关于modifier的使用
限于篇幅,我是以常用的属性来讲解,漏讲了一些请见谅,毕竟方法真的太多了,之后可能有用的新的效果,会穿插地讲些
本系列以往文章请查看此分类链接Jetpack compose学习
基本使用
我们直接以个简单的例子讲解下使用,设置Box布局的宽高各100dp,且内边距为16dp,背景色为绿色,代码如下
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: Dp)
size(height: Dp,width: Dp)
width
单独设置宽度
width(intrinsicSize: IntrinsicSize)
这个参数是自定义布局测量里的,本篇暂时不讲解width(width: Dp)
hegiht
单独设置高度
hegiht(intrinsicSize: IntrinsicSize)
这个参数是自定义布局测量里的,本篇暂时不讲解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
)
fillMaxSize(fraction: Float = 1f)
默认是1f,代表填充满父布局,如果设置为0.5f,则是填满父布局的0.5(即一半)
除此之外,也有单独给宽度或高度方法
= fillMaxWidth(fraction: Float = 1f)
= fillMaxHegiht(fraction: Float = 1f)
wrapContentSize
组件的控件宽高若是小与定义的最小宽高,会将组件进行排列的设置
wrapContentSize(
align: Alignment = Alignment.Center,
unbounded: Boolean = false
)
上面说的可能不是太好懂,以一个例子来说明吧
Box(
Modifier.sizeIn(minWidth = 40.dp, minHeight = 40.dp)
.wrapContentSize(Alignment.TopCenter)
.size(20.dp)
.background(Color.Blue)
)
我们设置了Box的组件的最小宽高为40dp,但此Box的宽高实际设置成了20dp,如果没有加上这个方法wrapContentSize
,那么最终渲染出的Box宽高其实是40dp
x 40dp
,且是蓝色背景
而由于我们加上了这个方法,最终渲染出的Box宽高就为20dp
x 20dp
,且排列对齐方式会按照wrapContentSize
中的align参数进行
同理,也有单独设置宽度或高度的方法
wrapContentHeight(
align: Alignment.Vertical = Alignment.CenterVertically,
unbounded: Boolean = false
)
//使用例子
Box(
Modifier.size(50.dp)
.wrapContentHeight(Alignment.CenterVertically)
.height(20.dp)
.background(Color.Blue)
)
wrapContentWidth(
align: Alignment.Horizontal = Alignment.CenterHorizontally,
unbounded: Boolean = false
)
//使用例子
Box(
Modifier.size(50.dp)
.wrapContentWidth(Alignment.CenterHorizontally)
.width(20.dp)
.background(Color.Blue)
)
padding
有四种不同的参数,各位看着用就行,之前文章中也是有详细讲解,这里不再赘述
padding(all: Dp)
点击事件类(点击 双击 长按)
clickable
给任意组件(包括布局)设置点击事件,且自带点击水波纹效果
clickable(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit
)
onClickLabel
和role
主要是为残疾人(应该是盲人)设置的属性,可以不用设置
此外,还有另外的参数列表
clickable(
interactionSource: MutableInteractionSource,
indication: Indication?,
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit
)
interactionSource
之前也有讲过,是用来判断按钮的点击状态,具体可以看之前讲解关于Button的使用的文章
indication
看文档说明是说用来绘制水波纹或者点击高亮的效果,具体使用没有深究,下面给个例子:
val interactionSource = remember { MutableInteractionSource() }
Column {
Text(
text = "Click me and my neighbour will indicate as well!",
modifier = Modifier
// clickable will dispatch events using MutableInteractionSource and show ripple
.clickable(
interactionSource = interactionSource,
indication = rememberRipple()
) {
/**do something */
}
.padding(10.dp)
)
Spacer(Modifier.requiredHeight(10.dp))
Text(
text = "I'm neighbour and I indicate when you click the other one",
modifier = Modifier
// this element doesn't have a click, but will show default indication from the
// CompositionLocal as it accepts the same MutableInteractionSource
.indication(interactionSource, LocalIndication.current)
.padding(10.dp)
)
}
效果如下图所示
combinedClickable
组合点击事件,可以给组件点击,双击,长按监听操作
不过,需要注意的是,此方法是实验性方法,也不知道后面版本更新会有所改变
combinedClickable(
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onLongClickLabel: String? = null,
onLongClick: () -> Unit = null,
onDoubleClick: () -> Unit = null,
onClick: () -> Unit
)
看方法很好理解,onLongClick
是长按操作,onDoubleClick
是双击操作,onClick
是点击操作
val context = LocalContext.current
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)
border
设置边框宽度和形状
border(border: BorderStroke, shape: Shape = RectangleShape)
border(width: Dp, color: Color, shape: Shape = RectangleShape))
border(width: Dp, brush: Brush, shape: Shape)
Brush是设置渐变,如下面的例子
//红蓝绿三色水平渐变
val gradientBrush = Brush.horizontalGradient(
colors = listOf(Color.Red, Color.Blue, Color.Green),
startX = 0.0f,
endX = 500.0f,
tileMode = TileMode.Repeated
)
Text(
"Text with gradient border",
modifier = Modifier.padding(10.dp).border(width = 2.dp, brush = gradientBrush, shape = CircleShape)
.padding(10.dp)
)
效果如下:
后期再出一篇讲解Brush的使用
background
设置背景及背景形状
background(color: Color, shape: Shape = RectangleShape)
background(brush: Brush, shape: Shape = RectangleShape,alpha: Float = 1.0f)
alpha是设置透明度
background有两种参数列表,具体使用也是与上面的类似,这里不过多赘述
阴影
shadow(elevation: Dp, shape: Shape = RectangleShape, clip: Boolean)
滚动效果
之前在讲解布局的时候有提及,Row和Column布局里面的子组件,宽高若是大于父组件就是导致子组件被隐藏,我们可以将其设置为滚动效果
但Compose没有Scrollview
,要想Row或Column实现滚动效果,就得使用modifier来实现
verticalScroll
horizontalScroll(
state: ScrollState,
enabled: Boolean = true,
flingBehavior: FlingBehavior? = null,
reverseScrolling: Boolean = false
)
flingBehavior这个参数不是很理解做什么用的..
Column(Modifier.verticalScroll(rememberScrollState())) {
repeat(10){
Box(
Modifier
.fillMaxWidth()
.height(200.dp)
){
Text(text = "测试$it")
}
}
}
效果如下:
如果不加上verticalScroll
,Column是无法向下滚动的
reverseScrolling设置为true的话,默认自动滚动到底部,效果如下所示
Column
一般和verticalScroll
连用实现垂直方向的滚动效果,而Row
则与horizontalScroll
连用
horizontalScroll
horizontalScroll(
state: ScrollState,
enabled: Boolean = true,
flingBehavior: FlingBehavior? = null,
reverseScrolling: Boolean = false
)
使用与上面的类似,这里不再赘述
scrollable
scrollable(
state: ScrollableState,
orientation: Orientation,
enabled: Boolean = true,
reverseDirection: Boolean = false,
flingBehavior: FlingBehavior? = null,
interactionSource: MutableInteractionSource? = null
)
没太搞懂这个主要是实现什么效果的..
文档的示例代码:
// actual composable state that we will show on UI and update in `Scrollable`
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.Red
val option2 = Color.Blue
var selectedOption by remember { mutableStateOf(option1) }
Column {
Text("Selected: $selectedOption")
Row {
listOf(option1, option2).forEach { color ->
val selected = selectedOption == color
Box(
Modifier
.size(100.dp)
.background(color = color)
.selectable(
selected = selected,
onClick = { selectedOption = color }
)
){
if(selected) Text(text = "已选",color = Color.White)
}
}
}
}
效果:
toggleable
类似复选框的勾选及不勾选
var checked by remember { mutableStateOf(false) }
// content that you want to make toggleable
Text(
modifier = Modifier.toggleable(value = checked, onValueChange = { checked = it }),
text = checked.toString()
)
效果如下:
变化类(旋转 缩放 放大)
aspectRatio
Box(Modifier.width(100.dp).aspectRatio(2f).background(Color.Green))
rotate
组件沿中心顺时针旋转,最高支持360°
//顺时针旋转45°
Box(
Modifier.rotate(45f)
.size(100.dp, 100.dp)
)
效果如下:
scale
缩放或放大
Box(
Modifier.scale(scaleX = 0.2f, scaleY = 0.5f)
.background(Color.Black)
.size(100.dp, 100.dp)
)
不过看实际效果,感觉是将宽和高都往中间缩放了
参考
Jetpack Compose学习(6)——关于Modifier的妙用的更多相关文章
- Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ...
- Jetpack Compose学习(2)——文本(Text)的使用
原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...
- Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用
原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...
- Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用
原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...
- Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用
原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ...
- Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单
Jetpack Compose学习(7)--MD样式架构组件Scaffold及导航底部菜单 | Stars-One的杂货小窝 Compose给我们提供了一个Material Design样式的首页组件 ...
- Jetpack Compose学习(8)——State及remeber
原文地址: Jetpack Compose学习(8)--State状态及remeber关键字 - Stars-One的杂货小窝 之前我们使用TextField,使用到了两个关键字remember和mu ...
- Jetpack Compose学习(1)——从登录页开始入门
原文地址:Jetpack Compose学习(1)--从登录页开始入门 | Stars-One的杂货小窝 Jetpack Compose UI在前几天出了1.0正式版,之前一直还在观望,终于是出了正式 ...
- Jetpack Compose 1.0 终于要投入使用了!
前言 Jetpack Compose 是用于构建原生界面的「新款 Android 工具包」.2021 Google IO 大会上,Google宣布:「Jetpack Compose 1.0 即将面世」 ...
随机推荐
- C# ThreadLocal源码追踪
ThreadLocal 字段成员: private Func<T>? _valueFactory; 一个获取默认值的委托 不同线程共享此成员. [ThreadStatic] private ...
- 创建File类 及 this.getClass().getResource()方法 用到的文件路径的问题
1 package test; 2 3 import java.io.*; 4 import java.util.Scanner; 5 6 public class TestResource { 7 ...
- myScript调研,电子手写板使用,纯干货
第二天进公司,就叫我调研myScript作为手写板的可行性,又不能不做,哎~ myScript效果十分的奈斯,前端用canvas手写的文字.数学字符,都可以识别然后转换,不知道myScript是不是你 ...
- 并发编程之:ThreadLocal
大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...
- Mysql 日期格式化 复杂日期区间查询
前言 最近在做项目涉及到Mysql的复杂日期查询,日期查询其实在数据库中查询其实还是用的挺多的,比如查询开始日期到结束日期的区间信息,查询日期小于有效日期的信息,查询当天的日期,明天的日期,做比较等. ...
- Nginx location 和 proxy_pass路径配置详解
目录 一.Nginx location 基本配置 1.1.Nginx 配置文件 1.2 .Python 脚本 二.测试 2.1.测试 location 末尾存在 / 和 proxy_pass末尾存在 ...
- (九)羽夏看C语言——C++番外篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...
- eclipse的C/C++开发搭建
环境 宿主机:ubuntu 16.04 交叉编译:gcc-linaro-4.9-2014.11 ubuntu自带源 eclipse 安装(想使用新版直接跳过) 安装eclipse sudo apt-g ...
- LeetCode通关:连刷十四题,回溯算法完全攻略
刷题路线:https://github.com/youngyangyang04/leetcode-master 大家好,我是被算法题虐到泪流满面的老三,只能靠发发文章给自己打气! 这一节,我们来看看回 ...
- jsPlumb开发流程设计器
前言 jsPlumb是一款开源软件,但jsPlumb toolkit是收费的. 本文主要使用jsPlumb实现一些简单的流程设计功能. 基础学习 首先引入jsplumb.min.js. <scr ...