赞
踩
为了得到的得到Uniapp的上位替代,最近打算使用Flutter开发。一般开发需要3个UI框架,icons库+UI框架+统计图
注意,后续的代码主要就是抄官方的案例来的
我习惯用vscode 的快捷键了,这里设置一下。
# 降低代码检验的标准,让我们更简单的使用dart
linter:
rules:
prefer_const_constructors: false
prefer_final_fields: false
use_key_in_widget_constructors: false
prefer_const_literals_to_create_immutables: false
prefer_const_constructors_in_immutables: false
avoid_print: false
日志打印使用[print]函数即可
print('hello flutter');
在[pubspec.yaml]中添加
name: namer_app description: A new Flutter project. publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 0.0.1+1 environment: sdk: '>=2.19.4 <4.0.0' # 这个就是Flutter对应的第三方库了 dependencies: flutter: sdk: flutter english_words: ^4.0.0 provider: ^6.0.0 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 flutter: uses-material-design: true
import 'package:english_words/english_words.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => MyAppState(), child: MaterialApp( title: 'Namer App', theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange), ), home: MyHomePage(), ), ); } } class MyAppState extends ChangeNotifier { var current = WordPair.random(); } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { var appState = context.watch<MyAppState>(); return Scaffold( body: Column( children: [ Text('A random idea:'), Text(appState.current.asLowerCase), ], ), ); } }
确保没有报错之后测试运行
return Scaffold(
body: Column(
children: [
Text('A random idea str:'),
Text(appState.current.asLowerCase),
//添加新的按钮
ElevatedButton(
onPressed: () {
print('button click');
},
child: Text('Next'))
],
),
);
MyApp就是项目的布局入口了,类似于Wpf/windows里面的窗口。标注这整个外部的容器的形状
详细的请看官方教程
目前看下来是单向数据流的向下数据流。在React和Vue中,都是自顶向下的数据流。什么是数据流呢?在我看来,就是数据改变自动触发,自动传递的就是数据流。
为什么一般都是向下数据流呢,因为我们认为,父节点的数据是先生成,范围广,更准确的。就好像是从上流的水往下流一样,可以更能保证整个项目的稳定行。如果是向上数据流的话,那随意添加一个子节点都可能导致父节点发送改动。如果是双向数据流的话,会导致数据流动的方向不明确,难以维护。
那子节点又是怎么通知父节点的呢?一般都是通过函数回调的形式,就是手动通知父节点。相当于需要更加繁琐,明确的操作来保证父节点的数据稳定。
更新视图需要用到notifyListeners,这个是用于通知视图的方法。在React和WPF中都是手动通知的,在Vue中是自动通知的。手动通知的好处就是可以操控。
注意:Dark有自己的命名规范,class大驼峰,类名和方法名都是小驼峰。
将[MyAppState]进行修改
//可通知视图修改的类 class MyAppState extends ChangeNotifier { //这个就相当于成员变量 var current = WordPair.random(); //手动声明回调函数,理论上来说,最好通过函数显性修改父节点属性 void getNext(){ current = WordPair.random(); // 手动通知刷新视图元素 notifyListeners(); } //手动通知 void notify(){ notifyListeners(); } }
return Scaffold( body: Column( children: [ Text('A random idea str:'), Text(appState.current.asLowerCase), //添加新的按钮 ElevatedButton( onPressed: () { print('button click'); //直接修改父节点属性 appState.current = WordPair.random(); //手动更新通知 appState.notify(); //上面两步等于下面一步,但是还是建议使用函数有限制的回调 //appState.getNext(); }, child: Text('Next')) ], ), );
为了防止父节点的数据遭到随意的修改,我们这里使用浅拷贝来复刻父节点的数据
class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { //拿到父节点,由于父节点是单例,所以不需要别名 var appState = context.watch<MyAppState>(); //为了解决复杂的代码逻辑,在函数开头拿到数据,而不是直接对父节点的数据进行修改 //这里是浅拷贝,不是深拷贝 var pair = appState.current; return Scaffold( body: Column( children: [ Text('A random idea str:'), // Text(appState.current.asLowerCase), Text(pair.asLowerCase), //添加新的按钮 ElevatedButton( onPressed: () { print('button click'); //直接修改父节点属性 // pair = WordPair.random(); //手动更新通知 // appState.notify(); //上面是浅拷贝的修改,无法反馈到父节点 appState.getNext(); }, child: Text('Next')) ], ), ); } }
所以我们的节点应该都是这么挂的
所以我现在的问题就是如果一个父节点挂载多个子节点,会如何。现在还不了解
右键Text节点,Refactor->Extarct Flutter Widget
在Padding布局外侧添加Card布局
@override
Widget build(BuildContext context) {
final theme = Theme.of(context); // ← Add this.
return Card(
color: theme.colorScheme.primary, // ← And also this.
child: Padding(
padding: const EdgeInsets.all(20),
child: Text(pair.asLowerCase),
),
);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。