当前位置: 首页 > news >正文

【Flutter入门到进阶】Flutter基础篇---布局

1 GridView网格布局组件

1.1 说明

1.1.1 图例

1.1.2 说明

        GridView网格布局在实际项目中用的也是非常多的,当我们想让可以滚动的元素使用矩阵方式排列的时 候。此时我们可以用网格列表组件GridView实现布局

GridView创建网格列表主要有下面三种方式

        1、可以通过GridView.count 实现网格布局

        2、可以通过GridView.extent 实现网格布局

        3、通过GridView.builder实现动态网格布局

1.2 常用属性

属性

1.3 案例

1.3.1 GridView.count 实现网格布局

        GridView.count构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以
        快速的创建横轴固定数量子元素的GridView

示例

//GridView.count 实现网格布局
class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return GridView.count(crossAxisCount: 3,childAspectRatio: 1.0,children: const <Widget>[Icon(Icons.home),Icon(Icons.ac_unit),Icon(Icons.search),Icon(Icons.settings),Icon(Icons.airport_shuttle),Icon(Icons.all_inclusive),Icon(Icons.beach_access),Icon(Icons.cake),Icon(Icons.circle),],);}
}

1.3.2 GridView.extent实现网格布局

        GridView.extent构造函数内部使用了SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以 快速的创建横轴子元素为固定最大长度的的GridView

//GridView.extent实现网格布局
class HomePage2 extends StatelessWidget {const HomePage2({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return GridView.extent(maxCrossAxisExtent: 80.0,childAspectRatio: 1.0,children: const <Widget>[Icon(Icons.home),Icon(Icons.ac_unit),Icon(Icons.search),Icon(Icons.settings),Icon(Icons.airport_shuttle),Icon(Icons.all_inclusive),Icon(Icons.beach_access),Icon(Icons.cake),Icon(Icons.circle),],);}
}

1.3.3 GridView.count 和 GridView.extent属性详解

//GridView.count 和 GridView.extent属性详解
class HomePage3 extends StatelessWidget {const HomePage3({Key? key}) : super(key: key);List<Widget> _getListData() {List<Widget> list = [];for (var i = 0; i < 20; i++) {list.add(Container(alignment: Alignment.center,color: Colors.blue,child: Text('这是第$i条数据',style: const TextStyle(color: Colors.white, fontSize: 20),),
// height: 400,  //设置高度没有反应));}return list;}@overrideWidget build(BuildContext context) {return GridView.count(crossAxisSpacing: 20.0,//水平子 Widget 之间间距mainAxisSpacing: 20.0,//垂直子 Widget 之间间距padding: const EdgeInsets.all(10),crossAxisCount: 2,//一行的 Widget 数量childAspectRatio: 0.8,//宽度和高度的比例children: _getListData(),);}
}

1.3.4 GridView实现动态列表

GridView.count实现动态列表

// GridView.count 实现动态列表class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);List<Widget> _getListData() {var tempList = listData.map((value) {return Container(decoration: BoxDecoration(border: Border.all(color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),child: Column(children: <Widget>[Image.asset(value['imageUrl']),const SizedBox(height: 12),Text(value['title'],textAlign: TextAlign.center,style: const TextStyle(fontSize: 20),)],),);}); // ('xxx','xxx')return tempList.toList();}@overrideWidget build(BuildContext context) {return GridView.count(crossAxisSpacing: 10.0,//水平子 Widget 之间间距mainAxisSpacing: 10.0,//垂直子 Widget 之间间距padding: const EdgeInsets.all(10),crossAxisCount: 2,//一行的 Widget 数量childAspectRatio: 0.7,//宽度和高度的比例children: _getListData(),);}
}

GridView.build实现动态列表

// GridView.builder实现动态列表class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);Widget _getListData(context, index) {return Container(decoration: BoxDecoration(border: Border.all(color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),child: Column(children: <Widget>[Image.asset(listData[index]['imageUrl']),const SizedBox(height: 12),Text(listData[index]['title'],textAlign: TextAlign.center,style: const TextStyle(fontSize: 20),)],),height: 400,//设置高度没有反应);}@overrideWidget build(BuildContext context) {return GridView.builder(//注意gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisSpacing: 10.0, //水平子 Widget 之间间距mainAxisSpacing: 10.0, //垂直子 Widget 之间间距crossAxisCount: 2, //一行的 Widget 数量),itemCount: listData.length,itemBuilder: _getListData,);}
}

2 Flutter Paddiing组件

2.1 说明        

        在html中常见的布局标签都有padding属性,但是Flutter中很多Widget是没有padding属性。这个时候 我们可以用Padding组件处理容器与子元素之间的间距

2.2 属性

        padding:padding值, EdgeInsetss设置填充的值

        child:子组件

2.3 示例

import 'package:flutter/material.dart';
import '../../res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("FLutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return GridView.count(padding: const EdgeInsets.all(10),crossAxisCount: 2,childAspectRatio: 1,children: [Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/1.png', fit: BoxFit.cover),),Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/2.png', fit: BoxFit.cover),),Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/3.png', fit: BoxFit.cover),),Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/4.png', fit: BoxFit.cover),),Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/5.png', fit: BoxFit.cover),),Padding(padding: const EdgeInsets.all(10),child: Image.asset('images/6.png', fit: BoxFit.cover),),],);}
}

3 线性布局(Row和Column)

3.1 Row 水平布局组件

3.1.1 Row属性

        mainAxisAlignment 主轴的排序方式

        crossAxisAlignment 次轴的排序方式

        children 组件子元素

3.1.2 示例

import 'package:flutter/material.dart';
import '../../res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("FLutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(height: double.infinity,width: double.infinity,color: Colors.black26,child: Row(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search, color: Colors.blue),IconContainer(Icons.send, color: Colors.orange),],),);}
}class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 100.0,width: 100.0,color: color,child: Center(child: Icon(icon, size: size, color: Colors.white)),);}
}

3.2 Column垂直布局组件

3.2.1 Column属性

        mainAxisAlignment 主轴的排序方式

        crossAxisAlignment 次轴的排序方式

        children 组件子元素

3.2.2 示例

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(height: double.infinity,width: double.infinity,color: Colors.black26,child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search, color: Colors.blue),IconContainer(Icons.send, color: Colors.orange),],),);}
}class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 100.0,width: 100.0,color: color,child: Center(child: Icon(icon, size: size, color: Colors.white)),);}
}

3.3 double.infinity 和double.maxFinite

3.3.1 说明

double.infinity 和double.maxFinite可以让当前元素的width或者height达到父元素的尺寸

3.3.2 底层代码

static const double nan = 0.0 / 0.0; static const double infinity = 1.0 / 0.0; static const double negativeInfinity = -infinity; static const double minPositive = 5e-324; static const double maxFinite = 1.7976931348623157e+308;

3.3.3 如下可以让Container铺满整个屏幕

Widget build(BuildContext context) {return Container(height: double.infinity,width: double.infinity,color: Colors.black26,child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search, color: Colors.blue),IconContainer(Icons.send, color: Colors.orange),],),);}


 

3.3.4 如下可以让Container的宽度和高度等于父元素的宽度高度

@override
Widget build(BuildContext context) {return Container(height: 400,width: 600,color: Colors.red,child: Container(height: double.maxFinite,width: double.infinity,color: Colors.black26,child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconContainer(Icons.home, color: Colors.red),IconContainer(Icons.search, color: Colors.blue),IconContainer(Icons.send, color: Colors.orange),],),),);
}

3.4 弹性布局(Flex Expanded)

3.4.1 说明

Flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用 Row或 Column会方便一 些,  因为 Row和 Column都继承自 Flex ,参数基本相同,所以能使用Flex的地方基本上都可以使用    Row或 Column 。 Flex本身功能是很强大的,它也可以和 Expanded组件配合实现弹性布局 。

3.4.2 水平弹性布局

示例1

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Flex(direction: Axis.horizontal,children: [Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1,child: IconContainer(Icons.search, color: Colors.orange),)],);}
}class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 100.0,width: 100.0,color: color,child: Center(child: Icon(icon, size: size, color: Colors.white)),);}
}

示例2

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Row(children: [Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1,child: IconContainer(Icons.search, color: Colors.orange),)],);}
}class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 100.0,width: 100.0,color: color,child: Center(child: Icon(icon, size: size, color: Colors.white)),);}
}

3.4.3 垂直弹性布局

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Column(children: [Expanded(flex: 2, child: IconContainer(Icons.home, color: Colors.red)),Expanded(flex: 1,child: IconContainer(Icons.search, color: Colors.orange),)],);}
}class IconContainer extends StatelessWidget {Color color;double size;IconData icon;IconContainer(this.icon,{Key? key, this.color = Colors.red, this.size = 32.0}): super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 100.0,width: 100.0,color: color,child: Center(child: Icon(icon, size: size, color: Colors.white)),);}
}

3.4.4 使用 Row 或 Co1umn 结合Expanded实现下面示例

示例图

代码

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return ListView(children: [Container(width: double.infinity,height: 200,color: Colors.black,),const SizedBox(height: 10),Row(children: [Expanded(flex: 2,child: SizedBox(height: 180,child: Image.asset("images/2.png",fit: BoxFit.cover),),),const SizedBox(width: 10),Expanded(flex: 1,child: SizedBox(height: 180,child: Column(children: [Expanded(flex: 1,child: SizedBox(width: double.infinity,child: Image.asset("images/3.png",fit: BoxFit.cover),),),const SizedBox(height: 10),Expanded(flex: 2,child: SizedBox(width: double.infinity,child: Image.asset("images/4.png",fit: BoxFit.cover),),)],),))],)],);}
}

4 Flutter Wrap组件

4.1 说明

        Wrap可以实现流布局,单行的Wrap跟Row表现几乎一致,单列的Wrap则跟Column表现几乎一致。但 Row与Column都是单行单列的,  Wrap则突破了这个限制,  mainAxis上空间不足时,则向crossAxis上 去扩展显示。

4.2 属性

4.2.1 direction

        主轴的方向,默认水平

4.2.2 alignment

        主轴的对其方式

4.2.3 spacing

        主轴方向上的间距

4.2.4 textDirection

        文本方向

4.2.5 verticalDirection

        定义了children摆放顺序,默认是down,见Flex相关属性介绍。

4.2.6 runAlignment

        run的对齐方式。  run可以理解为新的行或者列,如果是水平方向布局的话, run可以理解为新的一行

4.2.7 runSpacing

        run的间距

4.3 示例

import 'package:flutter/material.dart';
import '../../res/listData.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("FLutter App")),body: const LayoutDemo(),),);}
}class LayoutDemo extends StatelessWidget {const LayoutDemo({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Padding(padding: const EdgeInsets.all(3),child: Wrap(spacing: 5,runSpacing: 5,direction: Axis.vertical,alignment: WrapAlignment.start,runAlignment: WrapAlignment.center,children: <Widget>[Button("第1集", onPressed: () {}),Button("第2集", onPressed: () {}),Button("第3集", onPressed: () {}),Button("第4集", onPressed: () {}),Button("第5集", onPressed: () {}),Button("第6集", onPressed: () {}),Button("第7集", onPressed: () {}),Button("第8集", onPressed: () {}),Button("第9集", onPressed: () {}),Button("第10集", onPressed: () {}),Button("第11集", onPressed: () {}),Button("第12集", onPressed: () {}),Button("第13集", onPressed: () {}),Button("第14集", onPressed: () {}),Button("第15集", onPressed: () {}),Button("第16集", onPressed: () {}),Button("第17集", onPressed: () {}),Button("第18集", onPressed: () {}),],),);}
}class Button extends StatelessWidget {String text;void Function()? onPressed;Button(this.text, {Key? key, required this.onPressed}) : super(key: key);@overrideWidget build(BuildContext context) {return ElevatedButton(onPressed: onPressed,style: ButtonStyle(backgroundColor:MaterialStateProperty.all(const Color.fromARGB(255, 236, 233, 233)),foregroundColor: MaterialStateProperty.all(Colors.black45),),child: Text(text),);}
}

4.4 示例2

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const LayoutDemo(),),);}
}class LayoutDemo extends StatelessWidget {const LayoutDemo({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Padding(padding: const EdgeInsets.all(10),child: ListView(children: [Row(children: [Text("热搜",style: Theme.of(context).textTheme.headline6,)],),const Divider(),Wrap(spacing: 10,runSpacing: 12,children: [Button("女装", onPressed: () {}),Button("笔记本", onPressed: () {}),Button("玩具", onPressed: () {}),Button("文学", onPressed: () {}),Button("女装", onPressed: () {}),Button("时尚", onPressed: () {}),Button("女装", onPressed: () {}),Button("女装", onPressed: () {}),],),const SizedBox(height: 10),Row(children: [Text("历史记录",style: Theme.of(context).textTheme.headline6,)],),const Divider(),Column(children: const [ListTile(title: Text("女装"),),Divider(),ListTile(title: Text("时尚"),),Divider(),],),const SizedBox(height: 40),Padding(padding: const EdgeInsets.all(20),child: OutlinedButton.icon(onPressed: () {},style: ButtonStyle(foregroundColor: MaterialStateProperty.all(Colors.black38)),icon: const Icon(Icons.delete),label: const Text("清空历史记录")),)]),);}
}class Button extends StatelessWidget {String text;void Function()? onPressed;Button(this.text, {Key? key, required this.onPressed}) : super(key: key);@overrideWidget build(BuildContext context) {return ElevatedButton(onPressed: onPressed,style: ButtonStyle(backgroundColor:MaterialStateProperty.all(const Color.fromARGB(255, 236, 233, 233)),foregroundColor: MaterialStateProperty.all(Colors.black45),),child: Text(text),);}
}

5 层叠布局(Stack、  Align、Positioned)

5.1 Flutter Stack组件

5.1.1 说明

        Stack表示堆的意思,我们可以用Stack或者Stack结合Align或者Stack结合 Positiond来实现页面的定位 布局

5.1.2 属性

        alignment:配置所有子元素的显示位置

        children:子组件

5.1.3 示例

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 120.0,width: 120.0,color: Colors.blue.shade50,child: const Align(alignment: Alignment.topRight,child: FlutterLogo(size: 60,),),);}
}//Align结合Alignment 参数
class HomePage2 extends StatelessWidget {const HomePage2({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(height: 120.0,width: 120.0,color: Colors.blue.shade50,child: const Align(alignment: Alignment(2, 0.0),child: FlutterLogo(size: 60,),));}
}//Align结合Stack组件
class HomePage3 extends StatelessWidget {const HomePage3({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Center(child: Container(height: 400,width: 300,color: Colors.red,child: Stack(// alignment: Alignment.center,children: const <Widget>[Align(alignment: Alignment(1, -0.2),child: Icon(Icons.home, size: 40, color: Colors.white),),Align(alignment: Alignment.center,child: Icon(Icons.search, size: 30, color: Colors.white),),Align(alignment: Alignment.bottomRight,child: Icon(Icons.settings_applications,size: 30, color: Colors.white),)],),),);}
}

5.2 Flutter Stack Align

5.2.1 说明

        Align组件可以调整子组件的位置 , Stack组件中结合Align组件也可以控制每个子元素的显示位置

5.2.2 属性

        alignment:配置所有子元素的显示位置

        child:子组件

5.2.3 Align结合Container的使用

说明  

        FlutterLogo 是Flutter SDK 提供的一个组件,内容就是 Flutter 的 log

示例

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Center(child: Stack(alignment: Alignment.topLeft,children: [Container(height: 400,width: 300,color: Colors.red,),const Text("这是一个文本",style: TextStyle(fontSize: 40, color: Colors.amber),)],),);}
}

5.3 Flutter Stack Positioned

5.3.1 说明

        Stack组件中结合Positioned组件也可以控制每个子元素的显示位置

5.3.2 属性

        top:子元素距离顶部的距离

        bottom:子元素距离底部的距离

        left:子元素距离左侧距离

        right:子元素距离右侧距离

        child:子组件

        width:组件的高度   (注意:宽度和高度必须是固定值,没法使用double.infinity)

        height:子组件的高度

示例

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
} //Stack组件中结合Positioned组件也可以控制每个子元素的显示位置class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {// FlutterMediaQuery获取屏幕宽度和高度final size = MediaQuery.of(context).size;final width = size.width;final height = size.height;return Center(child: Container(height: height,width: width,color: Colors.red,child: Stack(alignment: Alignment.center,children: const <Widget>[Positioned(left: 10,child: Icon(Icons.home, size: 40, color: Colors.white),),Positioned(bottom: 0,left: 100,child: Icon(Icons.search, size: 30, color: Colors.white),),Positioned(right: 0,child: Icon(Icons.settings_applications,size: 30, color: Colors.white),)],),),);}
}// Flutter Stack Positioned固定导航案例
class HomePage2 extends StatelessWidget {const HomePage2({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {final size = MediaQuery.of(context).size;return Stack(children: [ListView(padding: const EdgeInsets.only(top: 45),children: const [ListTile(title: Text("这是一个标题 "),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),ListTile(title: Text("这是一个标题"),),],),Positioned(top: 0,left: 0,height: 40,width: size.width,child: Container(alignment: Alignment.center,color: Colors.black,child: const Text("你好FLutter",style: TextStyle(color: Colors.white),),))],);}
}

6 Flutter AspectRatio

6.1 说明

6.1.1 AspectRatio的作用是根据设置调整子元素child的宽高比。

6.1.2 AspectRatio首先会在布局限制条件允许的范围内尽可能的扩展,  widget的高度是由宽度和比率决定 的,类似于BoxFit中的contain,按照固定比率去尽量占满区域。

6.1.3 如果在满足所有限制条件过后无法找到一个可行的尺寸,  AspectRatio最终将会去优先适应布局限制条 件,而忽略所设置的比率。

6.2 属性

6.2.1 aspectRatio

        宽高比,最终可能不会根据这个值去布局,具体则要看综合因素,外层是否允许 按照这种比率进行布局,这只是一个参考值

6.2.2 child

        子组件

6.3 示例

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
} //Flutter AspectRatioclass MyApp extends StatelessWidget {const MyApp({Key? key}): super(key: key); // This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(title: const Text("Flutter App")),body: const HomePage(),),);}
}class HomePage extends StatelessWidget {const HomePage({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {// TODO: implement buildreturn Container(width: 200,color: Colors.yellow,child: AspectRatio(aspectRatio: 2.0 / 1.0,child: Container(color: Colors.red,),child: LayoutDemo(),),);}
}class LayoutDemo extends StatelessWidget {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn AspectRatio(aspectRatio: 3.0 / 1.0,child: Container(color: Colors.blue,),);}
}

相关文章:

【Flutter入门到进阶】Flutter基础篇---布局

1 GridView网格布局组件 1.1 说明 1.1.1 图例 1.1.2 说明 GridView网格布局在实际项目中用的也是非常多的&#xff0c;当我们想让可以滚动的元素使用矩阵方式排列的时 候。此时我们可以用网格列表组件GridView实现布局 GridView创建网格列表主要有下面三种方式 1、可以通过Gr…...

python海龟绘图

一、基础 &#xff08;一&#xff09;介绍 海龟绘图&#xff08;Turtle Graphics&#xff09;&#xff1a;“小海龟”turtle是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始…...

【计算机网络】数据链路层

概述 封装成帧 差错检验 可靠传输 实现机制 可靠传输的实现机制 停止等待协议 回退N帧协议 选择重传协议 【计算机网络】MAC帧和PPP帧&#xff08;定义使用范围区别共同点&#xff09;_GPNU_Log的博客-CSDN博客_ppp帧 PPP帧和以太网帧 | Mixoo 数据链路层的协议有PPP协…...

使用groovy代码方式解开gradle配置文件神秘面纱

来到这里的是不是都有以下疑问&#xff1a; 1.build.gradle配置文件结构好复杂啊&#xff0c;怎么记&#xff1f; 2.内部是怎么进行分析和执行的&#xff1f; 3.为什么可以在配置文件里面写groovy代码&#xff0c;怎么识别的&#xff1f; 4.怎么才能很方便的记住和快速上手…...

kafka入门到实战二(使用docker搭建kafka集群)

使用Docker搭建kafka单机/集群 拉取镜像&#xff1a;2.8.0之前&#xff0c;kafka都需要依赖zookeeper docker pull wurstmeister/kafka docker pull wurstmeister/zookeeper运行zookeeper镜像 docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper运行ka…...

【简化开发】lombok的使用、编译后的代码及源码

lombok的使用导入依赖一、getter、Setter、toString1、getter、Setter分别生成getxxx()和setxxx()方法2、toString生成toString()方法&#xff0c;按顺序打印类名称以及每个字段&#xff0c;并以逗号分隔二、NoArgsConstructor、RequiredArgsConstructor、AllArgsConstructor1、…...

在线就能用的主图设计素材,免费分享!

如何给自己的店铺商品设计专属的节日活动主图&#xff1f;没有节日活动的主体素材要如何设计&#xff1f;下面小编就分享一个在线素材设计工具&#xff0c;打开乔拓云&#xff0c;平台里面不仅有许多能使用的电商设计素材&#xff0c;还有许多的设计工具和模板能帮助你快速的实…...

【测绘程序设计】——计算卫星位置

本文分享了根据广播星历计算卫星于瞬时地固系下位置的计算程序(C#版)(注:瞬时地球坐标系坐标经极移改正即可获得协议地球坐标系坐标),相关源代码(完整工程,直接运行;包含实验数据)及使用示例如下。 目录 Part.Ⅰ 使用示例Part.Ⅱ 代码分析Chap.Ⅰ 数据结构Chap.Ⅱ 计…...

山东双软认证的基本条件

​一、山东双软认证的基本条件 "双软认证"是指软件产品评估和软件企业评估;企业申请双软认证除了获得软件企业和软件产品的认证资质&#xff0c;同时也是对企业知识产权的一种保护方式&#xff0c;更可以让企业享受国家提供给软件行业的税收优惠政策&#xff1b;我们…...

TPM 2.0实例探索3 —— LUKS磁盘加密(4)

接前文&#xff1a;TPM 2.0实例探索2 —— LUKS磁盘加密&#xff08;3&#xff09; 本文大部分内容参考&#xff1a; Code Sample: Protecting secret data and keys using Intel Platform... 二、LUKS磁盘加密实例 4. 将密码存储于TPM的PCR TPM平台配置寄存器&#xff08;…...

Linux连接RDP远程服务工具集记录

目录 rdesktop 安装 实例 xfreerdp 安装 实例 remmia 介绍 rdesktop 安装...

离散事件动态系统

文章目录离散事件动态系统ppt离散事件系统建模离散事件动态系统的基本组成元素离散事件动态系统仿真具体建模petri建模实例离散事件动态系统 ppt ppt 仿真建模步骤 离散事件系统建模 from&#xff1a;离散事件系统建模 离散事件动态系统的基本组成元素 &#xff08;1&am…...

无线WiFi安全渗透与攻防(二)之打造专属字典

系列文章 无线WiFi安全渗透与攻防(一)之无线安全环境搭建 打造专属字典 什么在破解之前先准备专用字典&#xff0c;因为对于一般家庭来说&#xff0c;常用 一个是预共享密钥PSK&#xff0c;一个是PIN码。 也不是所有的路由都开起了PIN码&#xff0c;一般都会开启域共享密钥…...

拥抱 Spring 全新 OAuth 解决方案

以下全文 Spring Authorization Server 简称为: SAS 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护&#xff0c;该项目将不会再进行任何的迭代目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用 作为 SpringBoot 3.0 的…...

前端开发与vscode开发工具介绍

文章目录1、前端开发2、vscode安装和使用2.1、下载地址2.2、插件安装2.3、设置字体大小2.4、开启完整的Emmet语法支持2.5、创建项目2.6、保存工作区2.7、新建文件夹和网页1、前端开发 前端工程师“Front-End-Developer”源自于美国。大约从2005年开始正式的前端工程师角色被行…...

C++---最长上升子序列模型---友好城市(每日一道算法2023.3.2)

注意事项&#xff1a; 本题为"线性dp—最长上升子序列的长度"的扩展题&#xff0c;所以dp思路这里就不再赘述。 题目&#xff1a; Palmia国有一条横贯东西的大河&#xff0c;河有笔直的南北两岸&#xff0c;岸上各有位置各不相同的N个城市。 北岸的每个城市有且仅有…...

maven高级知识。

目录 一、分模块开发 1、分模块开发设计 2、依赖管理 二、继承和聚合 1、聚合 2、继承 三、属性 1、基本介绍 2、版本管理 四、多环境配置与应用 1、多环境开发 2、跳过测试 五、私服 1、私服安装 2、私服仓库分类 一、分模块开发 1、分模块开发设计 ▶ 示意图 …...

Python 之 Pandas 处理字符串和apply() 函数、applymap() 函数、map() 函数详解

文章目录一、处理字符串1. 向量化字符串操作简介2. str 方法的简介二、apply() 函数详解三、applymap() 函数详解四、map() 函数详解一、处理字符串 当我们遇到一个超级大的 DataFrame&#xff0c;里面有一列类型为字符串&#xff0c;要将每一行的字符串都用同一方式进行处理&…...

汇川AM402和上位机C#ModebusTcp通讯

目录 一、测试任务 二、测试环境 三、PLC工程 1、组态配置 2、ip地址、端口号 3、全局变量定义 四、C#端Winform程序创建 1创建主界面 2、创建子窗口 3、运行生成&#xff0c;界面效果 4、Modebus协议说明 5、Modebus操作说明 六、测试 1、寄存器读测试 2、MW1300寄…...

给你一个电商网站,你如何测试?功能测试及接口测试思路是什么?

功能测试思路 1、注册测试&#xff1a; 测试注册表单是否可以正确提交用户信息&#xff1b; 测试注册表单是否有输入限制&#xff0c;例如密码长度、邮箱格式等&#xff1b; 测试注册后是否可以正常登录。 2、登录测试&#xff1a; 测试登录表单是否可以正确提交用户信息&…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...