- Article -

FLUTTER学习记录笔记

分类于 前端开发 标签 flutter dart 发表于2024-06-26 22:00

flutter 环境

Android Studio 2023.2.1

1.Vscode 安装扩展 Flutter和Dart

2.安装下载 Flutter SDK并设置bin路径

​ 解压在其他地方复制过来会丢失gi t信息

3.设置代理

```export PUB_HOSTED_URL=https://pub.flutter-io.cn  

export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn```

3.安装 Android Studio

​ 默认组件

4.运行 flutter doctor 检查

指定 sdk flutter config --android-sdk /Users/xusenlin/flutter/Android/sdk

钱少其他工具可以通过 Android Studio 的设置 -> languages -> Android SDK -> sdk tools来安装

同意协议 flutter doctor --android-licenses

flutter create demo && cd demo && flutter run

添加插件

运行flutter pub add webview_flutter将会在pubspec.yaml里添加依赖。

获取项目依赖 flutter pub get

当你安装Flutter时,Dart SDK会随之自动安装。Flutter会自动将Dart SDK捆绑在一起,并将其添加到系统的环境变量中。在大多数情况下,你不需要单独安装Dart SDK,因为Flutter会处理这一步。

如果你想找到Dart SDK的位置,可以通过以下方式之一:

  1. 通过Flutter命令行工具: 运行flutter doctor命令,它会显示Flutter和Dart的安装路径。
  2. 手动查找: 在Flutter安装目录中,通常会有一个名为bin/cache/dart-sdk的文件夹,其中包含Dart SDK。

一个布局 widget 可能只能包含一个或多个 widget 一个使用 child,多个使用 children。

你可以使用 mainAxisAlignmentcrossAxisAlignment 属性控制行或列如何对齐其子项。对于一行来说,主轴水平延伸,交叉轴垂直延伸。对于一列来说,主轴垂直延伸,交叉轴水平延伸。

笔记

导入包

import 'package:demo/routes.dart';
import 'package:flutter/material.dart';
import 'config/app.dart';
import '../kk/app.dart';

icon

https://fonts.google.com/icons

Dart

变量

Dart 是强类型语言,声明变量的方法:

函数

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理

对于只包含一个表达式的函数,可以使用简写语法:

bool isNoble(int atomicNumber)=> true ;   

函数参数可以使用[]放在最后表示此参数时可选的。

String say(String from, String msg, [String? device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

调用函数是必须按照顺序来传参数,但是后面的device是可选的。👆

还有一种使用{}来包裹参数的,可选的命名指定参数,也就是参数都是可选的,但是,传参时必须指定参数

void enableFlags({bool ? bold, bool ? hidden}) {
    // ... 
}
enableFlags(bold: true, hidden: false);//指定bold,hidden

mixin

Dart 是不支持多继承的,但是它支持 mixin,简单来讲 mixin 可以 “组合” 多个类

class Person {
  say() {
    print('say');
  }
}

mixin Eat {
  eat() {
    print('eat');
  }
}

mixin Walk {
  walk() {
    print('walk');
  }
}

mixin Code {
  code() {
    print('key');
  }
}

class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

Future 异步

(安装http模块 dart pub add http,导入导出规则)

定时器

Timer(const Duration(seconds: 2), () {
  print('定时器触发:${DateTime.now()}');
});
Timer.periodic(const Duration(seconds: 2), (time) {
  print('定时器触发:${DateTime.now()}');
});

Future (未来)与 JavaScript 中的 Promise 一样,返回 Future 类型的函数 有Future.thenFuture.catchErrorFuture.whenComplete可用。

Future.delayed(Duration(seconds: 2),(){
   //return "hi world!";
   throw AssertionError("Error");  
}).then((data){
   //执行成功会走到这里  
   print("success");
}).catchError((e){
   //执行失败会走到这里  
   print(e);
}).whenComplete((){
   //无论成功或失败都会走到这里
});

Future.waitPromise.all 一样。等待多个Future全部完成,一个不能出错。

async/await

Dart中的async/await 和JavaScript中的async/await功能是一样的:异步任务串行化。

其实,无论是在 JavaScript 还是 Dart 中,async/await 都只是一个语法糖,编译器或解释器最终都会将其转化为一个 Promise(Future)的调用链。

Stream

Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等。举个例子

Stream.fromFutures([
  // 1秒后返回结果
  Future.delayed(Duration(seconds: 1), () {
    return "hello 1";
  }),
  // 抛出一个异常
  Future.delayed(Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  // 3秒后返回结果
  Future.delayed(Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){

});

Widget 组件

flutter基础组件

有状态的组件一般配合 State 类使用,State 需要有一个build方法。无状态的组件也要有一个build方法。

Material 组件

//获得一 Widget 切换控制器
final PageController _pageController = PageController();

//通过控制器可以跳转到不同页面
 _pageController.jumpToPage(index);

//最后需要销毁控制器
void dispose() {
    _pageController.dispose();
    super.dispose();
  }
//展示,一般可以配合BottomNavigationBar来做tab切换动画
PageView(
  controller: _pageController,
  onPageChanged: (index) {
    setState(() {
      _selectedIndex = index;
    });
  },
  children: _tabContent,
),
  

布局组件示例

Container(
  child: Text('Container(容器)在UI框架中是一个很常见的概念,Flutter也不例外。'),
  padding: EdgeInsets.all(18.0), // 内边距
  margin: EdgeInsets.all(44.0), // 外边距
  width: 180.0,
  height:240,
  alignment: Alignment.center, // 子Widget居中对齐
  decoration: BoxDecoration( //Container样式
    color: Colors.red, // 背景色
    borderRadius: BorderRadius.circular(10.0), // 圆角边框
  ),
)
Padding(
  padding: EdgeInsets.all(44.0),
  child: Text('Container(容器)在UI框架中是一个很常见的概念,Flutter也不例外。'),
);
Scaffold(
  body: Center(child: Text("Hello")) // This trailing comma makes auto-formatting nicer for build methods.
);

路由&导航&参数

创建一个路由,有首页和 test 页面

import './pages/home/main.dart';
import './pages/test.dart';
import 'package:flutter/material.dart';



class Routes {
  static const String home = '/';
  static const String test = '/test';


  static Map<String, WidgetBuilder> getRoutes() {
    return {
      home: (context) => const Home(),
      test:(context) => const Test(),
    };
  }
}

将路由配置到 MaterialApp 组件

import 'package:flutter/material.dart';
import './config/app.dart';
import './routes.dart';


void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: appName,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      initialRoute: Routes.home,
      routes: Routes.getRoutes(),
    );
  }
}

创建一个user类,作为页面传递参数

class User {
  final String name;
  final int age;

  User({required this.name, required this.age});
}

在首页导航=>

ElevatedButton(
  onPressed: ()async {
    await Navigator.pushNamed(context, Routes.test,arguments: User(name: 'John Doe', age: 30));
  },
  child: const Text('Go to Test Page'),
),

Test 页面接收参数:

import '../../components/webView.dart';
import 'package:flutter/material.dart';
import 'home/tabContent/blog.dart';


class Test extends StatelessWidget {
  const Test({super.key});

  @override
  Widget build(BuildContext context) {
    final User user = ModalRoute.of(context)!.settings.arguments as User;
    return Scaffold(
      appBar: AppBar(
        title: Text('Test Page ${user.name}'),
      ),
      body:WebView(),
    );
  }
}

主题

ThemeData 是 Flutter 中用于定义应用程序整体主题的类。它包含许多属性,可以用来配置应用程序的视觉风格,如颜色、字体、图标、形状等。ThemeData 常用属性包括:

ColorScheme.fromSeed 返回的内容

ColorScheme.fromSeed 是一个工厂构造函数,用于通过一个种子颜色生成一个 ColorSchemeColorScheme 是一个用于定义应用程序颜色的类,包含一组预定义的颜色,可以用于统一应用程序中的颜色风格。

示例如下:

ColorScheme colorScheme = ColorScheme.fromSeed(seedColor: Colors.blue);

ColorScheme 包含的主要属性有:

通过 ColorScheme.fromSeed 生成的 ColorScheme,可以确保应用程序的颜色风格统一,并且颜色之间的对比度适合无障碍设计。