文章目录
前言
为了得到的得到Uniapp的上位替代,最近打算使用Flutter开发。一般开发需要3个UI框架,icons库+UI框架+统计图
相关链接

初始化项目
注意,后续的代码主要就是抄官方的案例来的

 
 
设置键盘映射
我习惯用vscode 的快捷键了,这里设置一下。
 
 
建议使用AnLink链接物理机。


项目配置

# 降低代码检验的标准,让我们更简单的使用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'))
        ],
      ),
    );

 
Flutter 项目结构
Flutter项目入口

Flutter的MyApp函数
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'))
        ],
      ),
    );
  }
}
思考
所以我们的节点应该都是这么挂的
- MyApp + MyAppState 
  - MyHomePage + appState=MyAppState,这里的appState都是向上一级的父节点属性
 
所以我现在的问题就是如果一个父节点挂载多个子节点,会如何。现在还不了解
修改布局
子节点重构
右键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),
      ),
    );
  }










