flutter,哎没办法,也是拉完了兄弟,学点跨端,指不准还能有一口饭吃。
state
widget树类似于这个dom树。所以的flutter画面都是由widget组成的。我是感觉flutter和compose react真的很像。与其说是节点,不如说我这个都是由组件组成,不同的组件拆成不同的颗粒度而已。
1 2 3 4 5 6 7 8 9 10 11 12 13
| // React 的 JSX <div> <Text>hello</Text> <Button onClick={handleClick}>click</Button> </div>
// Flutter 的 Widget Column( children: [ Text('hello'), ElevatedButton(onPressed: handleClick, child: Text('click')), ], )
|
然后这里也是类似于 React 的 useState / Compose 的 remember + mutableStateOf,flutter有一个StatefulWidget,也是记录状态的,而StatelessWidget就是不适用state记录的静态网页。
具体而言,就是你写了这个StatefulWidget,它你这里用到这些值,它都会监听状态的,改变了就会重建。
然后这里一个细节,就是它这里很像这个mvvm,viewmodel的感觉,它这里有个state,用来让数据和UI解耦。你这个statefulwidget需要实现一个createState的接口,然后这个state就表示你用这些数据来做什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Counter extends StatefulWidget { final String title; const Counter({super.key, required this.title});
@override State<Counter> createState() => CounterState(); }
class CounterState extends State<Counter> { int count = 0;
@override Widget build(BuildContext context) { return Column( children: [ Text(widget.title), Text('$count'), ElevatedButton( onPressed: () { setState(() { count++; }); }, child: Text('加一'), ), ], ); } }
|
怎么说呢,就flutter 会频繁地销毁和重建 Widget 对象,但 State 对象会保留。这样状态不会丢失
然后这里的下划线,就是当前文件私有。
provider/reader
这个也是和react很像啊,你一直往下面传值的话,有些值就是要一直用到的,比如我这个可能有个点击是否展开一些设置,这个设置页面是否打开这个bool值,有可能会被它里面的child用到,比如漫画,可能会需要判断某些手势是否需要拦截。这个时候就需要用到这种不用一直传值的,就外面写一个provider,然后里面就能拿到。然后这里的应该是有好几个,reader/select/watch。我用到的就是reader,这里还有很多问题,这里的reader是写的一个拓展函数。拓展函数就很像是这个kotlin的那个了,不过它这个还能命名,能用来分组区分具体干嘛来的。
布局
横向就是row,纵向column,然后好像还有stack,类似于帧布局framelayout,就一层层往上堆叠的这种吧。有一些自带的listview好像,记不太清了。点击是onTap,其他的也是类似,click改成tap。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ElevatedButton(onPressed: () { print('clicked'); }, child: Text('按钮'))
GestureDetector( onTap: () { print('tapped'); }, onDoubleTap: () { print('double tapped'); }, onLongPress: () { print('long pressed'); }, child: Text('点我'), )
Listener( onPointerDown: (event) { print('finger down at ${event.position}'); }, onPointerMove: (event) { print('finger moved'); }, onPointerUp: (event) { print('finger up'); }, child: Text('摸我'), )
|
这个东西,感觉是applywindowInsets里面的这个insets,用来专门做这个沉浸式的,能拿到导航栏边距这些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| dart
final size = MediaQuery.sizeOf(context); print('宽: ${size.width}, 高: ${size.height}');
final padding = MediaQuery.paddingOf(context); print('状态栏高: ${padding.top}, 底部导航: ${padding.bottom}');
final gestures = MediaQuery.systemGestureInsetsOf(context); print('左边缘手势区: ${gestures.left}');
|
语法糖
这个get啊,就函数前面加一个限定get,它这个东西就形式上,就能当这个属性来用,它不用写函数的括号。我看上去就有点像是这个kotlin的by委托来了。