ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Compose 组件 - 流式布局 FlowLayout(FlowColumn、FlowRow)

Compose 组件 - 流式布局 FlowLayout(FlowColumn、FlowRow) 官方页面一、概念流式布局能实时响应屏幕可用空间进行重排界面当一行或一列放不下里面的内容时会自动换行还允许元素使用权重Modifier.weight进行动态调整大小以将项目分配到容器中。FlowRowComposablefun FlowRow(modifier: Modifier Modifier,horizontalArrangement: Arrangement.Horizontal Arrangement.Start,verticalArrangement: Arrangement.Vertical Arrangement.Top,itemVerticalAlignment: Alignment.Vertical Alignment.Top,maxItemsInEachRow: Int Int.MAX_VALUE, //单行元素上限maxLines: Int Int.MAX_VALUE, //行数content: Composable FlowRowScope.() - Unit,)FlowColumnComposablefun FlowColumn(modifier: Modifier Modifier,verticalArrangement: Arrangement.Vertical Arrangement.Top,horizontalArrangement: Arrangement.Horizontal Arrangement.Start,itemHorizontalAlignment: Alignment.Horizontal Alignment.Start,maxItemsInEachColumn: Int Int.MAX_VALUE, //单列元素上限maxLines: Int Int.MAX_VALUE, //列数content: Composable FlowColumnScope.() - Unit,)1.1 主轴排列主轴是项的布局轴例如在FlowRow中项是水平排列的。以 FlowRow 举例。Arrangement.StartArrangement.CenterArrangement.EndArrangement.SpaceBetweenArrangement.SpaceAroundArrangement.spacedBy(8.dp)1.2 交叉轴排列交叉轴是与主轴方向相反的轴。例如在FlowRow中这是指垂直轴。以 FlowRow 举例。Arrangement.Top (Default)Arrangement.CenterArrangement.Bottom1.3 子元素对齐子元素在当前行内对齐也可以对一行中的某个子元素使用 Modifier.align() 进行单独设置。以 FlowRow 举例。Alignment.Top (Default)Alignment.BottomAlignment.CenterVertically1.4 单行/单列中的子元素数量限制以 FlowRow 举例。未设置上限默认maxItemsInEachRow 31.5 权重例如 FlowRow可调整每行中子元素所占宽度。详见官方页面吧。二、简单使用Composable fun Filters() { val filters listOf(Washer/Dryer, Ramp access, Garden, Cats OK, Dogs OK, Smoke-free) FlowRow(horizontalArrangement Arrangement.spacedBy(8.dp)) { filters.forEach { title - var selected by remember { mutableStateOf(false) } val leadingIcon: Composable () - Unit { Icon(Icons.Default.Check, null) } FilterChip( selected selected, onClick { selected !selected }, label { Text(title) }, leadingIcon if (selected) leadingIcon else null ) } } }三、进阶使用Composable fun AdapterScreen( windowWidthSizeClass: WindowWidthSizeClass currentWindowAdaptiveInfo().windowSizeClass.windowWidthSizeClass ) { FlowRow( modifier Modifier.fillMaxSize(), horizontalArrangement Arrangement.Center, verticalArrangement Arrangement.Center, maxItemsInEachRow 3 //可用空间再大一行也只有3个子元素 ) { //大型组件作为第一个直接放 Big() //对紧凑型来说小型组件横着放放不下会自动换行效果图横着显示2个 //对中等型和展开型来说用容器 FlowColumn 包裹小型组件使之成为一个整体 //充分利用纵向空间在容器中竖着放放不下会自动换列效果图竖着显示两个 if(windowWidthSizeClass WindowWidthSizeClass.COMPACT) { Small() Small() } else { FlowColumn { Small() Small() } } //中型组件同理小型组件 if(windowWidthSizeClass WindowWidthSizeClass.COMPACT) { Medium() Medium() } else { FlowColumn { Medium() Medium() } } } }3.1 保持子元素内部动画状态 movableContentOf()当流式布局进行重排的时候子元素的动画会被打断重新启动。借助可移动内容 Movable content可以在子元素被移动的时候不丢失动画状态。movableContentOf()public fun movableContentOf(content: Composable () - Unit): Composable () - Unitval smallContent remember { movableContentOf { Small() Small() } } FlowRow { if (windowSizeClass WindowWidthSizeClass.Compact) { smallContent() } else { FlowColumn { smallContent() } } }3.2 子元素位移动画当流式布局进行重排的时候子元素是瞬间移动的没有流畅自然的感觉。最外层使用 LookaheadScope 包裹能够让 Compose 在布局变化时执行中间测量过程并告知子元素这些中间状态。使用 Modifier.animateBounds() 构建一个自定义的 Modifier 传递给子元素构建时可以指定 boundsTransform 参数到自定义的 spring 规范从而定制动画的运行方式。//自定义动画 val boundsTransform { _: Rect, _: Rect- spring( dampingRatio Spring.DampingRatioNoBouncy, stiffness Spring.StiffnessMedium, visibilityThreshold Rect.VisibilityThreshold ) } //最外层包裹一下 LookaheadScope { //单独创建 Modifier 方便多次传参给子元素 val MyModifier Modifier.animateBounds( lookaheadScope thisLookaheadScope, boundsTransform boundsTransform ) val smallContent remember { movableContentOf { small(modifier MyModifier) //将自定义的 Modifier 传递给子元素 small(modifier MyModifier) } } FlowRow { if (windowSizeClass WindowWidthSizeClass.Compact) { smallContent() } else { FlowColumn { smallContent() } } } }
返回列表