Flutter 常见布局模型

Flutter的常见的布局模型有容器(Container)、弹性盒子布局(Flex、Row、Column、Expanded)、流式布局(Wrap、Flow)、层叠布局(Stack、Position)、滚动布局(ListView、GridView)等。
布局模型也都是 widget,很多布局widget都继承自Container,其布局UI树状图如图:
布局

布局容器 Container

创建一个项目:

flutter create buju

lib/main.dart 代码

import 'dart:math' as math;
import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Container(height: 50,width: 100,alignment: Alignment.center,decoration: BoxDecoration(color: Colors.grey,borderRadius: BorderRadius.all(Radius.circular(10.0)),border: Border.all(color: Colors.black, width: 2.0),),margin: EdgeInsets.fromLTRB(200, 50, 0, 0),transform: Matrix4.rotationZ(30 * math.pi / 180),child: Text("Container \n布局"),),),);}
}

从上面代码可以看到 Container 布局有很多属性:
color 设置容器的背景色。
width 设置容器的宽。
height 设置容器的高。
alignment 设置子widget的对齐方式,如居中。
decoration 设置背景装饰,如阴影、背景图等。
foregroundDecoration 设置前景装饰,比如前景色。
margin 设置容器等外边距。
padding 设置容器等内边距。
transform 设置形变,如需旋转、拉长等。
child 设置容器包裹的子Widget。
更多请见文档。

效果图如下:
1

弹性盒子布局

Flex

direction 设置主轴排列方向

Flex 有个重要的属性 direction,用来指定主轴的方向,子元素会按照主轴的方向排列。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Flex(direction: Axis.horizontal,children: <Widget>[Container(width: 30,height: 50,color: Colors.red,),Container(width: 30,height: 50,color: Colors.green,),Container(width: 30,height: 50,color: Colors.grey,),],),),);}
}

这里主轴方向是horizontal水平方向,效果图如下:
Flex
改成垂直direction: Axis.vertical,后的效果:
Flex

mainAxisAlignment 设置子元素排列方式

另一个重要属性是mainAxisAlignment,用来决定主轴的排列方式。
默认是start:mainAxisAlignment: MainAxisAlignment.start
end:指最后一个元素排在主轴的最后。这里以主轴水平方向排列为例,如下图:
1
center:所有子元素按照主轴方向依次排列,并居中显示在父容器中。如下图:
center
spaceAround:每个子元素之间的间隔相等,第一个元素和最后一个元素距离父容器的边距为孩子之间间距的一半。如下图:
spaceAround
spaceBetween:子元素两端对齐,第一个子元素和最后一个子元素分别位于容器中主轴的起始处和终止处,同时各个子元素之间的间隔相等,如下图:
spaceBetween
spaceEvenly: 各个子元素之间的间隔相等,同时第一个子元素和最后一个子元素距离父容器的边距也为各子元素之间的间隔。
spaceEvenly

mainAxisSize 设置主轴大小

mainAxisSize默认是max,Flex容器占据主轴全部空间。
还可以设置为min,Flex容器尽可能占据少的主轴空间。

direction: Axis.horizontal,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,

mainAxisSize
这里把Flex容器设置为最小的大小,导致三个子元素挤在了一起。

crossAxisAlignment 设置交叉轴对齐方式

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Flex(direction: Axis.horizontal,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[Container(width: 30,height: 100,color: Colors.red,),Container(width: 30,height: 50,color: Colors.green,),Container(width: 30,height: 50,color: Colors.grey,),],),),);}
}

crossAxisAlignment 用来设置元素在交叉轴方向上的对齐方式。
默认值是center,各个子元素在交叉轴上居中对齐。如下图(这里以主轴沿水平方向):
center
end:子元素布局在Flex容器交叉轴方向的尾部。
end

start:子元素布局在Flex容器交叉轴方向的头部。
start
stretch:子元素填充满交叉轴方向的空间。
stretch

verticalDirection 设置交叉轴布局的对齐方向

这个属性和上面的crossAxisAlignment属性配合使用,用于指定交叉轴布局的对齐方向
默认值是down,表示默认对齐的方向是从上到下,crossAxisAlignment默认start时,三个元素在顶部。
如果将verticalDirection改成up,表示从下到上,crossAxisAlignment还是默认start时,效果图如下:
verticalDirection
Row 和 Column 都继承自Flex,所以Flex都属性同样适用于Row和Column,只是预先指定好了主轴的方向。
Row表示在水平方向上布局子元素,主轴方向是水平方向。
Column表示在垂直方向上布局子元素,主轴方向是垂直方向。
Flex 更多参数见:https://api.flutter-io.cn/flutter/widgets/Flex-class.html

Expanded 按比例缩放

Expanded 布局能让子元素能够按照一定的比例缩放,来填充满父容器在主轴方向上剩余的剩余空间。通常,Expanded 组件通常是作为Flex 组件的子组件使用。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Flex(direction: Axis.horizontal,children: <Widget>[Expanded(flex: 1,child: Container(height: 150,color: Colors.red,),),Expanded(flex: 1,child: Container(height: 150,color: Colors.green,),),Expanded(flex: 1,child: Container(height: 150,color: Colors.blue,),),],),),);}
}

效果图:
Expanded
如果把 Expanded 的 Flex 属性分别设置为 1,2,3,得到的效果图如下:
Flex

流式布局

在弹性布局中,如果宽度或高度超过屏幕尺寸,会抛出异常:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Flex(direction: Axis.horizontal,children: <Widget>[Container(width: 150,height: 100,color: Colors.red,),Container(width: 280,height: 50,color: Colors.green,),Container(width: 50,height: 50,color: Colors.grey,),],),),);}
}

1

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 105 pixels on the right.

这是因为弹性和子布局模型是线性的,不会自动换行。

Wrap 自动换行的容器

Wrap支持子元素自动换行,默认主轴水平方向。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Wrap(direction: Axis.horizontal,spacing: 10,runAlignment: WrapAlignment.start,verticalDirection: VerticalDirection.down,runSpacing: 10,children: <Widget>[Container(width: 150,height: 150,color: Colors.red,),Container(width: 200,height: 50,color: Colors.green,),Container(width: 50,height: 50,color: Colors.grey,),Container(width: 200,height: 150,color: Colors.black,),],),),);}
}

alignment、crossAxisAlignment、verticalDirection 与 Flex 的同名属性作用相同。
runAlignment 用来设置新一行或新一列的对齐方式。默认值是start,如果主轴方向是水平方向,start就是在交叉轴方向上从顶部开始布局子元素,如下图。end 是在交叉轴方向上从底部开始布局子元素。center 设置居中对齐,子元素会从交叉轴方向上父容器的中心开始布局。
runAlignment

Flow 布局允许用户自定义布局规则,具体参数见:https://api.flutter-io.cn/flutter/widgets/Flow-class.html

层叠布局:绝对定位

Stack 布局类似Web开发中的绝对定位。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: Center(child: Stack(children: <Widget>[Container(width: 150,height: 150,color: Colors.red,),Positioned(left: 8.0,right: 8.0,top: 8.0,child: Text('测试'),)],),)),);}
}

这个例子是对Text组件和Container组件的重叠,其中Positioned是定位组件,只能放在Stack中。
Stack

滚动布局

ListView 处理大量数据

当数据量特别大时,上面的布局方式实现起来会非常麻烦,而用滚动布局,直接将数据放入滚动布局模型的 children 数据中即可。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: ListView.builder(itemCount: 50,itemExtent: 50,itemBuilder: (BuildContext context, int index) {return Container(height: 50,child: Row(crossAxisAlignment: CrossAxisAlignment.center,children: [Text('索引: ${index + 1}')],),);})),);}
}

1
详细参数见文档:https://api.flutter-io.cn/flutter/widgets/ListView-class.html。

ListView.separated 增加分割线

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: ListView.separated(itemCount: 50,separatorBuilder: (BuildContext context, int ndex) {return Divider();},itemBuilder: (BuildContext context, int index) {return SizedBox(height: 50,child: Row(crossAxisAlignment: CrossAxisAlignment.center,children: [Text('索引: ${index + 1}')],),);})),);}
}

1

GridView 构建多行多列表格

GridView 的创建需要一个 delegate 代表,即属性 gridDelegate , Flutter SDK 默认提供了两个 SliverGridDelegate 的子类,分别是: SliverGridDelegateWithFixedCrossAxisCount 和 SliverGridDelegateWithMaxCrossAxisExtent 。

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: GridView(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 8, mainAxisSpacing: 8),children: [Container(width: 50,height: 50,color: Colors.red,),Container(width: 50,height: 50,color: Colors.red,),Container(width: 50,height: 50,color: Colors.red,),Container(width: 50,height: 50,color: Colors.red,),Container(width: 50,height: 50,color: Colors.red,),Container(width: 50,height: 50,color: Colors.red,),],)),);}
}

效果图:
1

动态创建 GridView

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(),body: GridView.builder(gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 8,mainAxisSpacing: 8,crossAxisSpacing: 8,childAspectRatio: 2.0),itemBuilder: (BuildContext context, int index) {return Container(color: Colors.red,width: 50,height: 50,);}),),);}
}

1
maxCrossAxisExtent 设置条目的宽度。
mainAxisSpacing 设置主轴的间隔。
crossAxisSpacing 设置交叉轴间隔。
childAspectRatio 设置子元素的宽高比。

相关链接

https://docs.flutter.cn/ui/layout/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/18860.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习框架探秘|TensorFlow:AI 世界的万能钥匙

在人工智能&#xff08;AI&#xff09;蓬勃发展的时代&#xff0c;各种强大的工具和框架如雨后春笋般涌现&#xff0c;而 TensorFlow 无疑是其中最耀眼的明星之一。它不仅被广泛应用于学术界的前沿研究&#xff0c;更是工业界实现 AI 落地的关键技术。今天&#xff0c;就让我们…

TypeScript 与后端开发Node.js

文章目录 一、搭建 TypeScript Node.js 项目 &#xff08;一&#xff09;初始化项目并安装相关依赖 1、创建项目目录并初始化2、安装必要的依赖包 &#xff08;二&#xff09;配置 TypeScript 编译选项&#xff08;如模块解析方式适合后端&#xff09; 二、编写服务器代码 &a…

DDD该怎么去落地实现(3)通用的仓库和工厂

通用的仓库和工厂 我有一个梦&#xff0c;就是希望DDD能够成为今后软件研发的主流&#xff0c;越来越多研发团队都转型DDD&#xff0c;采用DDD的设计思想和方法&#xff0c;设计开发软件系统。这个梦想在不久的将来是有可能达成的&#xff0c;因为DDD是软件复杂性的解决之道&a…

国家队出手!DeepSeek上线国家超算互联网平台!

目前,国家超算互联网平台已推出 DeepSeek – R1 模型的 1.5B、7B、8B、14B 版本,后续还会在近期更新 32B、70B 等版本。 DeepSeek太火爆了!在这个春节档,直接成了全民热议的话题。 DeepSeek也毫无悬念地干到了全球增速最快的AI应用。这几天,国内的云计算厂家都在支持Dee…

内容中台驱动企业数字化内容管理高效协同架构

内容概要 在数字化转型加速的背景下&#xff0c;企业对内容管理的需求从单一存储向全链路协同演进。内容中台作为核心支撑架构&#xff0c;通过统一的内容资源池与智能化管理工具&#xff0c;重塑了内容生产、存储、分发及迭代的流程。其核心价值在于打破部门壁垒&#xff0c;…

算法1-1 玩具谜题

题目描述 小南有一套可爱的玩具小人&#xff0c;它们各有不同的职业。 有一天&#xff0c;这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈&#xff0c;它们有的面朝圈内&#xff0c;有的面朝圈外。如下图&#xff1a; 这时 singer 告诉小南一个谜题&…

vs2022支持.netframework4.0

下载nuget包 .netframework4.0 解压nuget 复制到C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 参考 https://www.cnblogs.com/bdqczhl/p/18670152 https://blog.csdn.net/xiaomeng1998_/article/details/135979884

数据治理常用的开源项目有哪些?

数据治理是企业在大数据时代中确保数据质量、安全性和可用性的关键环节。开源项目在数据治理中扮演着重要角色&#xff0c;提供了灵活、经济高效且功能强大的解决方案。以下是一些常用的开源数据治理项目&#xff1a; Apache Atlas&#xff1a; 功能&#xff1a;元数据管理、数…

登录弹窗效果

1&#xff0c;要求 点击登录按钮&#xff0c;弹出登录窗口 提示1&#xff1a;登录窗口 display:none 隐藏状态&#xff1b; 提示2&#xff1a;登录按钮点击后&#xff0c;触发事件&#xff0c;修改 display:block 显示状态 提示3&#xff1a;登录窗口中点击关闭按钮&#xff0…

docker nginx 配置文件详解

在平常的开发工作中&#xff0c;我们经常需要访问静态资源&#xff08;图片、HTML页面等&#xff09;、访问文件目录、部署项目时进行负载均衡等。那么我们就会使用到Nginx&#xff0c;nginx.conf 的配置至关重要。那么今天主要结合访问静态资源、负载均衡等总结下 nginx.conf …

Python+appium实现自动化测试

目录 一、工具与环境准备 二、开始测试 1、插上手机&#xff0c;打开usb调试&#xff0c;选中文件传输&#xff0c;我这里用华为手机为例 2、启动Appium Server GUI​编辑 3、启动 Inspector Session 4、录制脚本 使用Python和Appium进行自动化测试是一种常见的移动应用…

DeepSeek正重构具身大模型和人形机器人赛道!

中国人工智能公司DeepSeek&#xff08;深度求索&#xff09;以“低成本、高效率、强开放”的研发范式横空出世&#xff0c;火遍并震撼全球科技圈&#xff1b;DeepSeek展现出来的核心竞争力&#xff0c;除了低成本及推理能力&#xff0c;更重要的是开源模型能力追赶上了最新的闭…

Facebook精准获客:外贸企业如何通过社群营销将产品推广到海外

作为全球用户量超40亿的社交平台&#xff0c;Facebook已成为外贸企业拓展海外市场的重要渠道。本文将系统解析基于Facebook平台的高效获客策略&#xff0c;重点针对手机壳等消费电子品类&#xff0c;提供可复制的精准客户开发方案&#xff0c;并且可以利用AI社媒引流王工具进行…

尚硅谷课程【笔记】——大数据之Hadoop【一】

课程视频链接&#xff1a;尚硅谷Hadoop3.x教程 一、大数据概论 1&#xff09;大数据概念 大数据&#xff08;Big Data&#xff09;&#xff1a;指无法再一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发…

JMeter工具介绍、元件和组件的介绍

Jmeter功能概要 JDK常用文件目录介绍 Bin目录&#xff1a;存放可执行文件和配置文件 Docs目录&#xff1a;是Jmeter的API文档&#xff0c;用于开发扩展组件 printable_docs目录&#xff1a;用户帮助手册 lib目录&#xff1a;存放JMeter依赖的jar包和用户扩展所依赖的Jar包…

【云安全】云原生- K8S kubeconfig 文件泄露

什么是 kubeconfig 文件&#xff1f; kubeconfig 文件是 Kubernetes 的配置文件&#xff0c;用于存储集群的访问凭证、API Server 的地址和认证信息&#xff0c;允许用户和 kubectl 等工具与 Kubernetes 集群进行交互。它通常包含多个集群的配置&#xff0c;支持通过上下文&am…

springboot整合mybatis-plus(保姆教学) 及搭建项目

一、Spring整合MyBatis (1)将MyBatis的DataSource交给Spring IoC容器创建并管理&#xff0c;使用第三方数据库连接池(Druid&#xff0c;C3P0等)代替MyBatis内置的数据库连接池 (2)将MyBatis的SqlSessionFactory交给Spring IoC容器创建并管理&#xff0c;使用spring-mybatis整…

数据结构6

一、哈希散列--通讯录查找 #include "hash.h" #include <stdio.h> #include <stdlib.h> #include <string.h>//int *a[10];int hash_function(char key) {if (key > a && key < z){return key - a;}else if (key > A && …

Java 大视界 -- 全球数据治理格局下 Java 大数据的发展路径(89)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

基于CanMV IDE 开发软件对K210图像识别模块的开发

简介 CanMV IDE 是一款专为 K210 芯片设计的图形识别 Python 软件&#xff0c;它提供了强大的功能&#xff0c;帮助开发者轻松实现基于 K210 芯片的图形识别应用。无论你是初学者还是经验丰富的开发者&#xff0c;CanMV IDE 都能为你提供便捷的开发环境和丰富的资源。 硬件资…