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; }); }, )), ); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
2017-02-12 java堆溢出
2017-02-12 虚拟机内存中数据细节
2017-02-12 JVM内存区域