Flutter之页面布局一
目录:
- 1、页面布局一
- 2、无状态组件StatelessWidget和有状态组件StatefulWidget
- 2.1、无状态组件示例
- 2.2、有状态组件示例
- 2.3、在 widget 之间共享状态
- 1、使用 widget 构造函数
- 2、使用 InheritedWidget
- 3、使用回调
- 3、布局小组件
- 3.1、布置单个 Widget
- 3.2、容器
- 3.3、垂直或水平布局多个 widget
- 3.4、在行和列内对齐 Widget
- 3.5、在行和列中调整小组件的大小
- 3.6、滚动 Widget
- 3.7、自适应布局
- 4、center和container的区别
- 5、Material app和非Material app应用的区别
- 6、构建布局示例一
1、页面布局一

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp( // Root widget//展示的是顶部区域部分home: Scaffold(appBar: AppBar(title: const Text('My Home Page'),),body: Center(child: Builder(builder: (context) {//纵向展示文本,盒子,以及按钮等return Column(children: [const Text('Hello, World!'),const SizedBox(height: 20),ElevatedButton(onPressed: () {print('Click!');},child: const Text('A button'),),],);},),),),);}
}
2、无状态组件StatelessWidget和有状态组件StatefulWidget
2.1、无状态组件示例
import 'package:flutter/material.dart';
import 'package:flutter_haoke/pages/home/info/data.dart';
import 'package:flutter_haoke/pages/home/info/index_widget.dart';class Info extends StatelessWidget {final bool showTitle;final List<InfoItem> dataList;const Info({Key? key, this.showTitle = false, this.dataList = infoData}): super(key: key);Widget build(BuildContext context) {return Container(child: Column(children: [if (showTitle)Container(padding: EdgeInsets.all(10),alignment: Alignment.centerLeft,child: Text("更多资讯",style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600),),),Column(children: dataList.map((e) {return InfoItemWidget(e);}).toList(),)],),);}
}
2.2、有状态组件示例
class CounterWidget extends StatefulWidget {State<CounterWidget> createState() => _CounterWidgetState();
}class _CounterWidgetState extends State<CounterWidget> {int _counter = 0;void _incrementCounter() {setState(() {_counter++;});}Widget build(BuildContext context) {return Text('$_counter');}
}
有状态组件通过State对象来存储可变状态。
2.3、在 widget 之间共享状态

1、使用 widget 构造函数
由于 Dart 对象是通过引用传递的,因此 widget 定义 对象。 你传递给 widget 的构造函数的任何状态 可用于构建其 UI:
class MyCounter extends StatelessWidget {final int count;const MyCounter({super.key, required this.count});Widget build(BuildContext context) {return Text('$count');}
}
这使得您的小部件的其他用户很明显知道 他们需要提供什么才能使用它:
Column(children: [//使用构造函数来传递值MyCounter(count: count,),MyCounter(count: count,),TextButton(child: Text('Increment'),onPressed: () {setState(() {count++;});},)],
)
2、使用 InheritedWidget
手动将数据向下传递 widget 树可能很详细 并导致不需要的样板代码, 所以 Flutter 提供了 InheritedWidget, 它提供了一种在父 widget 中高效托管数据的方法 这样子 widget 就可以访问它们,而无需将它们存储为 field。
要使用 ,请扩展类 并使用 . 在 build 方法中调用的 widget 创建由 Flutter 框架管理的依赖项, 以便任何依赖于此 rebuild 的 widget 当此小组件使用新数据重新构建时 并返回 true。
class MyState extends InheritedWidget {const MyState({super.key,required this.data,required super.child,});final String data;static MyState of(BuildContext context) {// This method looks for the nearest `MyState` widget ancestor.final result = context.dependOnInheritedWidgetOfExactType<MyState>();assert(result != null, 'No MyState found in context');return result!;}// This method should return true if the old widget's data is different// from this widget's data. If true, any widgets that depend on this widget// by calling `of()` will be re-built.bool updateShouldNotify(MyState oldWidget) => data != oldWidget.data;
}
接下来,调用 从小部件的方法 需要访问 shared 状态:of()build()
class HomeScreen extends StatelessWidget {const HomeScreen({super.key});Widget build(BuildContext context) {var data = MyState.of(context).data;return Scaffold(body: Center(child: Text(data),),);}
}
3、使用回调
class MyWidget extends StatefulWidget {_MyWidgetState createState() => _MyWidgetState();
}class _MyWidgetState extends State<MyWidget> {//初始值为falsebool _value = false;void _handleValueChanged(bool value) {setState(() {_value = value;});// 在这里执行值发生变化时的操作}Widget build(BuildContext context) {return Switch(//监听switch发生改变,_value赋值给value时触发 _handleValueChanged(value)value: _value,onChanged: _handleValueChanged,);}
}
在上面的示例中,我们创建了一个Switch小部件,并将_value变量作为其值传递。当Switch的值发生变化时,会调用_handleValueChanged函数,并在函数中更新_value的值。通过调用setState函数,我们告诉Flutter框架重新构建小部件以反映新的值。
3、布局小组件

3.1、布置单个 Widget

3.2、容器


3.3、垂直或水平布局多个 widget


3.4、在行和列内对齐 Widget


3.5、在行和列中调整小组件的大小



3.6、滚动 Widget



3.7、自适应布局

4、center和container的区别
Center组件:
Center组件继承自Align,主要用于将子组件居中显示。它通过设置alignment属性为Alignment.center来实现这一点。Center组件的代码示例如下:
class MyHomeBody extends StatelessWidget {Widget build(BuildContext context) {return Center(child: Icon(Icons.pets, size: 36, color: Colors.red),);}
}
在这个例子中,Icon组件会被居中显示。Center组件的主要特点是它会自动调整其父容器的尺寸以适应子组件的尺寸,并将其居中。
Container组件:
Container组件则更加通用,主要用于创建一个矩形容器,可以包含其他组件,并提供多种定制化属性,如背景色、边框、圆角、阴影等。Container可以调整其内部子组件的对齐方式、边距、填充等。Container的代码示例如下:
class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: 'Container Learn',home: Scaffold(body: Center(child: Container(child: Text('Alignment center', style: TextStyle(fontSize: 40.0),),alignment: Alignment.center,width: 500.0,height: 400.0,color: Colors.lightBlue,),),),);}
}
在这个例子中,Text组件被包含在一个Container中,并通过alignment属性设置为居中对齐。Container提供了更多的布局和样式控制选项。
5、Material app和非Material app应用的区别

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const String appTitle = 'Flutter layout demo';return MaterialApp(title: appTitle,home: Scaffold(appBar: AppBar(title: const Text(appTitle)),body: const Center(child: Text('Hello World'),),),);}
}

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return Container(decoration: const BoxDecoration(color: Colors.white),child: const Center(child: Text('Hello World',textDirection: TextDirection.ltr,style: TextStyle(fontSize: 32, color: Colors.black87),),),);}
}
默认情况下,非 Material app 不包含 AppBar、标题和背景颜色。如果你希望在非 Material app 中使用这些功能,则必须自己构建它们。
6、构建布局示例一

import 'package:flutter/material.dart';void main() => runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {const String appTitle = 'Flutter layout demo';return MaterialApp(title: appTitle,home: Scaffold(appBar: AppBar(title: const Text(appTitle)),body: const Center(// child: Text('Hello World'),children: [ImageSection(image: 'images/lake.jpg',),TitleSection(name: 'Oeschinen Lake Campground',location: 'Kandersteg, Switzerland',),ButtonSection(),TextSection(description:'Lake Oeschinen lies at the foot of the Blüemlisalp in the ''Bernese Alps. Situated 1,578 meters above sea level, it ''is one of the larger Alpine Lakes. A gondola ride from ''Kandersteg, followed by a half-hour walk through pastures ''and pine forest, leads you to the lake, which warms to 20 ''degrees Celsius in the summer. Activities enjoyed here ''include rowing, and riding the summer toboggan run.',),),);}
}

class TitleSection extends StatelessWidget {const TitleSection({super.key, required this.name, required this.location});final String name;final String location;Widget build(BuildContext context) {return Padding(padding: const EdgeInsets.all(32),child: Row(children: [Expanded(/*1*/child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [/*2*/Padding(padding: const EdgeInsets.only(bottom: 8),child: Text(name,style: const TextStyle(fontWeight: FontWeight.bold),),),Text(location, style: TextStyle(color: Colors.grey[500])),],),),/*3*/Icon(Icons.star, color: Colors.red[500]),const Text('41'),],),);}
}

class ButtonSection extends StatelessWidget {const ButtonSection({super.key});Widget build(BuildContext context) {final Color color = Theme.of(context).primaryColor;return SizedBox(child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ButtonWithText(color: color, icon: Icons.call, label: 'CALL'),ButtonWithText(color: color, icon: Icons.near_me, label: 'ROUTE'),ButtonWithText(color: color, icon: Icons.share, label: 'SHARE'),],),);}}class ButtonWithText extends StatelessWidget {const ButtonWithText({super.key,required this.color,required this.icon,required this.label,});final Color color;final IconData icon;final String label;Widget build(BuildContext context) {return Column(// ···);}}

class TextSection extends StatelessWidget {const TextSection({super.key, required this.description});final String description;Widget build(BuildContext context) {return Padding(padding: const EdgeInsets.all(32),child: Text(description, softWrap: true),);}
}

class ImageSection extends StatelessWidget {const ImageSection({super.key, required this.image});final String image;Widget build(BuildContext context) {return Image.asset(image, width: 600, height: 240, fit: BoxFit.cover);}
}
相关文章:
Flutter之页面布局一
目录: 1、页面布局一2、无状态组件StatelessWidget和有状态组件StatefulWidget2.1、无状态组件示例2.2、有状态组件示例2.3、在 widget 之间共享状态1、使用 widget 构造函数2、使用 InheritedWidget3、使用回调 3、布局小组件3.1、布置单个 Widget3.2、容器3.3、垂…...
架构思维: 数据一致性的两种场景深度解读
文章目录 Pre案例数据一致性问题的两种场景第一种场景:实时数据不一致不要紧,保证数据最终一致性就行第二种场景:必须保证实时一致性 最终一致性方案实时一致性方案TCC 模式Seata 中 AT 模式的自动回滚一阶段二阶段-回滚二阶段-提交 Pre 架构…...
大数据knox网关API
我们过去访问大数据组件,如sparkui,hdfs的页面,以及yarn上面看信息是很麻烦的一件事。要记每个端口号,比如50070,8090,8088,4007,如果换到另一个集群,不同版本࿰…...
UI测试(2)
1、HTML 是用来描述网页的一种语言。 指的是超文本标记语言 (Hyper Text Markup Language) ,HTML 不是一种编程语言,而是一种标记语言 (markup language) 负责定义页面呈现的内容:标签语言:<标签名>标签值<标签名>&am…...
【Tauri2】015——前端的事件、方法和invoke函数
目录 前言 正文 准备 关键url 获取所有命令 切换主题set_theme 设置大小 获得版本version 名字name 监听窗口移动 前言 【Tauri2】005——tauri::command属性与invoke函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146581991?spm1001.2014.3001.…...
密码学基础——分组密码的运行模式
前面的文章中文我们已经知道了分组密码是一种对称密钥密码体制,其工作原理可以概括为将明文消息分割成固定长度的分组,然后对每个分组分别进行加密处理。 下面介绍分组密码的运行模式 1.电码本模式(ECB) 2.密码分组链接模式&…...
Android SELinux权限使用
Android SELinux权限使用 一、SELinux开关 adb在线修改seLinux(也可以改配置文件彻底关闭) $ getenforce; //获取当前seLinux状态,Enforcing(表示已打开),Permissive(表示已关闭) $ setenforce 1; //打开seLinux $ setenforce 0; //关闭seLinux二、命令查看sel…...
Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)
Python----计算机视觉处理(Opencv:道路检测之道路透视变换) Python----计算机视觉处理(Opencv:道路检测之提取车道线) Python----计算机视觉处理(Opencv:道路检测之车道线拟合) Python----计算机视觉处理࿰…...
基于飞桨框架3.0本地DeepSeek-R1蒸馏版部署实战
深度学习框架与大模型技术的融合正推动人工智能应用的新一轮变革。百度飞桨(PaddlePaddle)作为国内首个自主研发、开源开放的深度学习平台,近期推出的3.0版本针对大模型时代的开发痛点进行了系统性革新。其核心创新包括“动静统一自动并行”&…...
docker初始环境搭建(docker、Docker Compose、portainer)
docker、Docker Compose和portainer的安装部署、使用 docker、Docker Compose和portainer的安装部署、使用一.安装docker1.失败的做法2.首先卸载旧版本(没安装则下一步)3.配置下载的yum来源,不然yum search搜不到4.安装启动docker5.替换国内源…...
开源RuoYi AI助手平台的未来趋势
近年来,人工智能技术的迅猛发展已经深刻地改变了我们的生活和工作方式。 无论是海外的GPT、Claude等国际知名AI助手,还是国内的DeepSeek、Kimi、Qwen等本土化解决方案,都为用户提供了前所未有的便利。然而,对于那些希望构建属于自…...
element-ui自制树形穿梭框
1、需求 由于业务特殊需求,想要element穿梭框功能,数据是二级树形结构,选中左边数据穿梭到右边后,左边数据不变。多次选中左边相同数据进行穿梭操作,右边数据会多次增加相同的数据。右边数据穿梭回左边时,…...
Linux系统学习Day04 阻塞特性,文件状态及文件夹查询
知识点4【文件的阻塞特性】 文件描述符 默认为 阻塞 的 比如:我们读取文件数据的时候,如果文件缓冲区没有数据,就需要等待数据的到来,这就是阻塞 当然写入的时候,如果发现缓冲区是满的,也需要等待刷新缓…...
Module模块化
导出:export关键字 export var color "red"; 重命名导出 在模块中使用as用导出名称表示本地名称。 import { add } from "./05-module-out.js"; 导入: import关键字 导入单个绑定 import { sum } from "./05-module-out.js&…...
Python基础——Pandas库
对象的创建 导入 Pandas 时,通常给其一个别名“pd”,即 import pandas as pd。作为标签库,Pandas 对象在 NumPy 数组基础上给予其行列标签。可以说,列表之于字典,就如 NumPy 之于 Pandas。Pandas 中,所有数…...
C++: 类型转换
C: 类型转换 (一)C语言中的类型转换volatile关键字 修饰const变量 (二)C四种强制类型转换1. static_cast2. reinterpret_cast3. const_cast4. dynamic_cast总结 (三)RTTI (一)C语言中的类型转换 在C语言中…...
[ctfshow web入门] 零基础版题解 目录(持续更新中)
ctfshow web入门 零基础版 前言 我在刷题之前没有学过php,但是会python和C,也就是说,如果你和我一样会一门高级语言,就可以开始刷题了。我会以完全没学过php的视角来写题解,你也完全没有必要专门学习php,这…...
【蓝桥杯】动态规划:线性动态规划
1. 最长上升子序列(LIS) 1.1. 题目 想象你有一排数字,比如:3, 1, 2, 1, 8, 5, 6 你要从中挑出一些数字,这些数字要满足两个条件: 你挑的数字的顺序要和原来序列中的顺序一致(不能打乱顺序) 你挑的数字要一个比一个大(严格递增) 问:最多能挑出多少个这样的数字? …...
STM32——DAC转换
DAC简介 DAC,全称:Digital-to-Analog Converter,扑指数字/模拟转换器 ADC和DAC是模拟电路与数字电路之间的桥梁 DAC的特性参数 1.分辨率: 表示模拟电压的最小增量,常用二进制位数表示,比如:…...
Kafka的索引设计有什么亮点
想获取更多高质量的Java技术文章?欢迎访问Java技术小馆官网,持续更新优质内容,助力技术成长 Java技术小馆官网https://www.yuque.com/jtostring Kafka的索引设计有什么亮点? Kafka 之所以能在海量数据的传输和处理过程中保持高…...
在深度学习中,如何统计模型的 FLOPs(浮点运算次数) 和 参数量(Params)
在深度学习中,统计模型的FLOPs(浮点运算次数)和参数量(Params)是评估模型复杂度和计算资源需求的重要步骤。 一、参数量(Params)计算 参数量指模型中所有可训练参数的总和,其计算与…...
智能手表该存什么音频和文本?场景化存储指南
文章目录 为什么需要“场景化存储”?智能手表的定位手机替代不了的场景碎片化的场景存储 音频篇:智能手表该存什么音乐和音频?运动场景通勤场景健康场景 文本篇:哪些文字信息值得放进手表?(部分情况可使用图…...
Linux之Shell脚本--命令提示的写法
原文网址:Linux之Shell脚本--命令提示的写法-CSDN博客 简介 本文介绍Linux的Shell脚本命令提示的写法。 场景描述 在写脚本时经常会忘记怎么使用,需要进行命令提示。比如:输入-h参数,能打印用法。 实例 新建文件:…...
Logo语言的进程
Logo语言的进程与发展 引言 Logo语言是一种专为儿童和教育目的而设计的编程语言,其独特之处在于其简洁的语法和直观的图形化界面,旨在帮助学生理解程序设计的基本概念。由于其在教育领域的广泛应用,Logo语言在编程教育史上占据了重要的地位…...
Day19 -实例:xcx逆向提取+微信开发者工具动态调试+bp动态抓包对小程序进行资产收集
思路: 拿到源码后的测试方向: Step1、xcx逆向提取源码 00x1 先将曾经使用小程序记录删除 00x2 访问小程序 例:汉川袁老四小程序 00x3 将文件给xcx进行逆向解包 xcx工具的目录下,wxpack文件夹内 Step2、微信开发者工具进行动态…...
鸿蒙Arkts开发飞机大战小游戏,包含无敌模式,自动射弹,暂停和继续
飞机大战可以把飞机改成图片,目前包含无敌模式,自动射弹,暂停和继续的功能 代码如下: // 定义位置类 class GamePosition {x: numbery: numberconstructor(x: number, y: number) {this.x xthis.y y} }Entry Component struct…...
ECharts配置优化
优化 ECharts 配置可以从性能优化、视觉优化和可维护性优化三个方面入手,下面我给你详细展开几个实用方向: ✅ 一、性能优化(大数据量 or 页面卡顿时重点考虑) 使用 setOption 的 notMerge 和 lazyUpdate chart.setOption(option,…...
从基础算力协作到超智融合,超算互联网助力大语言模型研习
一、背景 大语言模型(LLMs)的快速发展释放出了AI应用领域的巨大潜力。同时,大语言模型作为 AI领域的新兴且关键的技术进展,为 AI 带来了全新的发展方向和应用场景,给 AI 注入了新潜力,这体现在大语言模型独…...
M1使用docker制作镜像xxl-job,供自己使用
很苦逼一个情况,m1的docker假如不翻墙,我们找不到xxl-job,所以我们要自己制作 首先先去下载xxl-job源码https://gitee.com/xuxueli0323/xxl-job 你把它拉去到idea中 拉去成功后,进入这个xxl-job目录 执行 mvn clean package -Dmaven.test.skiptrue(这一步…...
Spring Boot 集成Redis 的Lua脚本详解
1. 对比Lua脚本方案与Redis自身事务 对比表格 对比维度Redis事务(MULTI/EXEC)Lua脚本方案原子性事务命令序列化执行,但中间可被其他命令打断,不保证原子性Lua脚本在Redis单线程中原子执行,不可中断计算能力仅支持Red…...
