Flutter笔记 - 布局类组件
布局类组件
Row水平方向排列
- textDirection 水平方向子组件布局顺序。
- mainAxisSize 占用空间,默认MainAxisSize.MAX
- mainAxisAligment 对齐方式
MainAxisAligment.start 初始方向对齐
MainAxisAligment.ltr 左对齐
MainAxisAligment.rtl 右对齐
MainAxisAligment.end 和MainAxisAligment.start相反
MainAxisAligment.center 居中对齐 - verticalDirection:处置对齐方向,默认从上到下VerticalDirection.down
- crossAxisAligment 子组件纵轴对齐方式
crossAxisAligment.start 顶部对齐
crossAxisAligment.start 底部对齐
children:子组件数组
弹性布局Flex
沿着水平或者垂直方向排列。
flex 比例
Spacer为Expandes的包装类
import 'package:flutter/material.dart';
class FlexLayoutRouter extends StatelessWidget {
const FlexLayoutRouter({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
height: 30,
color: Colors.green,
)),
Expanded(
flex: 1,
child: Container(
height: 30,
color: Colors.green,
))
],
),
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: SizedBox(
height: 100,
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
height: 30,
color: Colors.grey,
)),
const Spacer(
flex: 2,
),
Expanded(
flex: 1,
child: Container(
height: 30,
color: Colors.black,
)),
],
),
),
)
],
);
}
}
流式布局
spaceing:主轴子Widget间距。
runSpacing:纵轴间距。
runAligment:纵轴对齐方式。
例子:
import 'package:flutter/material.dart';
class WrapRoute extends StatelessWidget{
const WrapRoute({super.key});
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Wrap(
spacing: 8.0,
runSpacing: 4.0,
alignment: WrapAlignment.center,
children: const <Widget>[
Chip(label: Text("A"),
avatar: CircleAvatar(backgroundColor: Colors.blue,child: Text("A")),
),
Chip(label: Text("B"),
avatar: CircleAvatar(backgroundColor: Colors.blue,child: Text("B")),
),
Chip(label: Text("C"),
avatar: CircleAvatar(backgroundColor: Colors.blue,child: Text("C")),
),
Chip(label: Text("D"),
avatar: CircleAvatar(backgroundColor: Colors.blue,child: Text("D")),
),
],
)
],
);
}
}
GestureDetector
一次完整的手势过程是指用户手指按下到抬起的整个过程,期间,用户按下手指后可能会移动,也可能不会移动。GestureDetector对于拖动和滑动事件是没有区分的,他们本质上是一样的。GestureDetector会将要监听的组件的原点(左上角)作为本次手势的原点,当用户在监听的组件上按下手指时,手势识别就会开始。
- DragDownDetails.globalPosition:当用户按下时,此属性为用户按下的位置相对于屏幕(而非父组件)原点(左上角)的偏移。
- DragUpdateDetails.delta:当用户在屏幕上滑动时,会触发多次Update事件,delta指一次Update事件的滑动的偏移量。
- DragEndDetails.velocity:该属性代表用户抬起手指时的滑动速度(包含x、y两个轴的),示例中并没有处理手指抬起时的速度,常见的效果是根据用户抬起手指时的速度做一个减速动画。
import 'package:flutter/material.dart';
class DragWidget extends StatefulWidget {
const DragWidget({super.key});
@override
DragState createState() => DragState();
}
class DragState extends State<DragWidget>
with SingleTickerProviderStateMixin<DragWidget> {
double _top = 0.0;
double _left = 0.0;
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
top: _top,
left: _left,
child: GestureDetector(
child: const CircleAvatar(child: Text("A")),
// 手指按下,全局位置
onPanDown: (DragDownDetails e) {
print("按下:${e.globalPosition}");
},
// 滑动过程中
onPanUpdate: (DragUpdateDetails e) {
setState(() {
// dx 为x轴偏移量
_left = _left + e.delta.dx;
_top = _top + e.delta.dy;
});
},
// 滑动结束的时候
onPanEnd: (DragEndDetails e) {
print("速度:${e.velocity}");
},
))
],
);
}
}
onScaleUpdate 缩放监听
import 'package:flutter/material.dart';
class ZoomWidget extends StatefulWidget {
const ZoomWidget({super.key});
@override
ZoomWidgetState createState() => ZoomWidgetState();
}
class ZoomWidgetState extends State<ZoomWidget> {
double _width = 200.0; //通过修改图片宽度来达到缩放效果
@override
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
child: Image.asset("./graphics/ic_launcher.png"),
onScaleUpdate: (ScaleUpdateDetails details) {
setState(() {
_width = 200 * details.scale.clamp(.8, 10.0);
});
},
),
);
}
}
GestureRecognizer
GestureRecognizer
的作用就是通过 Listener
来将原始指针事件转换为语义手势,GestureDetector
直接可以接收一个子widget。
例子:变颜色的TextSpan
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class ChangeColorWidget extends StatefulWidget {
const ChangeColorWidget({super.key});
@override
ChangeColorWidgetState createState() => ChangeColorWidgetState();
}
class ChangeColorWidgetState extends State<ChangeColorWidget> {
// 手势识别器
TapGestureRecognizer tapGestureRecognizer = TapGestureRecognizer();
//手势开关
bool toggle = false;
@override
Widget build(BuildContext context) {
return Center(
child: Text.rich(TextSpan(
text: "点我变颜色",
style: TextStyle(
fontSize: 30,
color: toggle ? Colors.green : Colors.red,
),
recognizer: tapGestureRecognizer
..onTap = () {
setState(() {
toggle = !toggle;
});
},
)),
);
}
}