Flutter 布局
[TOC]
flutter 有三层树结构:Widget、Element、RenderObject
import 'package:flutter/material.dart';
main()=>runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "app title",
home: JLHomePage(),
);
}
}
class JLHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("基础Widget"),
),
body: JLHomeContent(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>print("浮动按钮"),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
class JLHomeContent extends StatefulWidget {
@override
_JLHomeContentState createState() => _JLHomeContentState();
}
class _JLHomeContentState extends State<JLHomeContent> {
final imgURL = "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=116882428,1733900798&fm=26&gp=0.jpg";
@override
Widget build(BuildContext context) {
return Text("dd");
}
}
class ImageExtensionDemo extends StatelessWidget {
// 1. 占位图的问题
// 2. 图片缓存:flutter默认给图片做缓存,最多1000张,最大100M。
const ImageExtensionDemo({
Key key,
@required this.imgURL,
}) : super(key: key);
final String imgURL;
@override
Widget build(BuildContext context) {
return FadeInImage(
// 设置过渡动画时间
fadeOutDuration: Duration(milliseconds: 1),
fadeInDuration: Duration(milliseconds: 1),
placeholder: AssetImage("assets/images/a_dot_ham.png"),
image: NetworkImage(imgURL));
}
}
class ButtonExtensionDemo extends StatelessWidget {
const ButtonExtensionDemo({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
// 1. button 上下有一定的间距 padding
// 2. 默认button有默认的宽高 88*36
// 3. 去除button的内边距
ButtonTheme(// 处理默认的最小宽高
minWidth: 30,
height: 10,
child: FlatButton(
// 清除内边距
padding: EdgeInsets.all(0),
// 清除外边距
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: Colors.red,
onPressed: (){},
child: Text("FaltBtn1")
),
),
FlatButton(
// materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onPressed: (){},
color: Colors.red,
child: Text("FaltB tn2"),
),
SizedBox(height: 10,),// 设置间距
Container(
// 给button设置宽高,不能直接给btn设置,需要包裹一层Container,然后用btn填充
// double.infinity 代表最大,能填充多大填多大
width: double.infinity,
height: 40,
child: FlatButton(
onPressed: (){},
color: Colors.blue,
child: Text("登 录",
style: TextStyle(fontSize: 20,color: Colors.white),),
)
],
);
}
}
class IconExtensionDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
//Icon 是字体图标
//1. 字体图标是矢量图,放大不会失真
//2. 可以设置颜色
//3. 图标很多是,占据控件更小
// return Icon(Icons.pets, size: 300,color: Colors.orange,);
// return Icon(IconData(0xe91d,fontFamily: 'MaterialIcons') , size: 300,color: Colors.orange,);
// 1. Text 中不能直接使用编码,需要转换 0xe91d-> unicode编码
return Text("\ue91d",style: TextStyle(fontSize: 100,color: Colors.orange,fontFamily: 'MaterialIcons'),);
}
}
单子布局
Align -> Center,Container,Padding
flutter 中的坐标系为: (0, 0) 是中心点。极值(-1, 1)
-1
|
|
-1------0------->1
|
|
↓
1
Container layout
RenderWidget -> RenderObject ->
{constraints 约束
BoxConstraint
minWidth minHeight
maxWidth maxHeight}
子组件在父组件的范围内调整Size 大小,子组件超出会报错超出安全区域。
不同的子组件对于同样的约束,表现可能不同。
多子布局
Row Column Stack
Row和Column都是继承自Flex组件,类似CSS中的Flex布局
Row的特点:水平方向尽可能大的占领空间,水平方向也是希望包裹内容,
垂直方向包裹内容。
/*
* Flex(direction: Axis.horizontal); = Row
* Flex(direction: Axis.vertical); = Column
* 实际开发中不常用Flex
* */
/*
* MainAxisAlignment:
* - start 主轴开始位置挨个摆放元素
* - end 主轴结束位置挨个摆放元素
* - center 主轴中心位置挨个摆放元素(默认值)
* - spaceBetween 左右两边为0,其他平分间距
* - spaceAround 左右两边间距为其他间距的一半
* - spaceEvenly 所有间距平分
*
* CrossAxisAlignment:
* - start 交叉轴开始位置挨个摆放元素
* - end 交叉轴结束位置挨个摆放元素
* - center 交叉轴中心位置挨个摆放元素(默认值)
* - baseline 基线对齐 CSS,文字排版,四线三格,基线:X下边的线,有文本才有效果
* - stretch 先让交叉轴row占据较大的空间,将所有的子Widget交叉轴的高度,拉升到最大
* */
Column:
收缩+拉伸
/*
* 拉伸
* Flexible 将屏幕剩余空间集中分配,设置拉伸
* - flex:
* Expended -> Flexible(fit: FlexFit.tight) 通常工程中,用这个更多,很少用Flexible
* 空间分配问题:flex 设置了之后,宽度就失效了,之后和flex比例相关了,
* 和css不一样,css有一套公式
*
*
* 收缩 也是用Expanded
*
* */
Expanded(
// flex: 1,
child: Container(width: 160,height: 80, color: Colors.red,)
),
Stack 层叠组件
/*
* Stack 层叠布局组件
* 根据 alignment: AlignmentDirectional.center, 为原点,按数组顺序叠放
* 默认大小是包裹内容
* fit: expand 将子元素拉伸到尽可能大
* - overflow: 超出部分如何处理 overflow: Overflow.visible,查出部分依然可见,默认不可见
*
* Positioned 定位
* */
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Container()
)