Flutter知识积累

1 mounted:判断页面是否被释放,如果释放了就不进行渲染

if (mounted) {
  setState(() {
  });
}


2 GlobalKey的使用:

final GlobalKey<_UserInfoItemState> _globalKey = GlobalKey();

final String? userName = _globalKey.currentState?.widget.userName;

final String? userPhone = _globalKey.currentState?.userPhone;

3 安卓设备启动图片的大小

mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
320*480
480*800
720*1280
1080*1920
3840*2160
4 断言assert 

如果assert 的判断为true, 则继续执行下面的语句。反之抛出一个异常。

5 计算Text内容高度TextPainter

  double get descInfoHeight {
    final TextPainter painter = TextPainter(
      locale: WidgetsBinding.instance!.window.locale,
      maxLines: 2,
      textDirection: TextDirection.ltr,
      text: TextSpan(
        text: "",
        style: TextStyle(
          color: const Color(0xFF666666),
          fontSize: 14.sp,
          fontWeight: FontWeight.w500,
        ),
      ),
    );
    painter.layout(maxWidth: 170.w);
    return painter.height;
  }

6 计算item内容高度

  void calculateContentHeight() {
    Future<void>.delayed(const Duration(), () {
      if (!mounted) {
        return;
      }
      final RenderBox renderBox = context.findRenderObject() as RenderBox;
      print("width = ${renderBox.size.width}, height = ${renderBox.size.height}");
    });
  }

7 const和final

const:赋值的内容必须在编译时已经确定

final:赋值时,可以动态获取,赋值的内容在运行时已经确定

8 dynamic和Object

dynamic调用方法时,编译不会报错,运行时存在安全隐患

Object类型,调用方法时,编译会报错

9 Dart语法:

Dart是单线程的

 Dart中的函数不支持方法重载

10
设置高斯模糊 ImageFiltered

 SizeBox 设置水平方向、垂直方向的间距

用三个单引号表示多行字符串 '''         ‘’'

集合类型Set:元素无序,不重复


11 ??=  赋值操作 
    
当变量有值,使用自己的值

当变量为null,使用后面的内容进行赋值
    
12 级联语法:

final p2 = Person()
           ..name = "why"
           ..run()
           ..eat()
           ..swim();

final p1 = Person();
p1.name = 'why’;
p1.run();
p1.eat();
p1.swim();
  
13 await
await 关键字必须在 async 函数内部使用

14 设置头像圆角

CircleAvatar
    
ClipOval

ClipRRect
    
Container + BoxDecoration + DecorationImage

15 CustomScrollView

slivers
    SliverAppBar
    SliverGrid
    SliverList

16  检测左上角的返回操作
  
外层包装一层WillPopScope,实现onWillPop方法

 返回为true: 使用系统提供的返回方法

返回为false:自定义返回方法
   
17 Icon 字体图标和图片图标

字体图标矢量图放大后不会失真

字体图标可以设置颜色

字体图标很多时,占据空间较小

18 build方法的执行时机:

Widget build(BuildContext context)

返回界面进行渲染的Widget

当Widget第一次被创建;当父Widget发生改变,子Widget会被重新构建

19 mixin混入

 mixin 关键字定义一个类,其他类通过with关键字进行混入。

with 非必须实现方法,可以不实现mixin类中已经实现的方法

Dart为了支持多重继承,引入了mixin关键字,mixin就相当于将其他类的能力混入到当前类,唯一的限制就是mixin类无法拥有构造函数。这样可以避免混入多个类时,父类构造方法的调用冲突。
 
20 隐式接口

 implements实现多个抽象类、普通类

implements 必须实现方法
    
可实现抽象类,普通类(多实现,实现多个类、抽象类)
    
一个类通过implements实现多个抽象类,必须实现抽象类的所有方法(未实现和已实现的方法)
   
21 extends

继承,可继承抽象类、普通类(单继承,只能继承一个类)
    
22 抽象类

关键字修饰:abstract
    
抽象类不能初始化
 
抽象类中的抽象方法必须被子类实现
  
抽象类中已经实现的方法可以不被子类重写
    
23 常量构造方法

const 修饰

常量构造方法的类中,所有成员变量必须是final修饰
    
24 工厂构造方法

 factory关键字修饰
    
可以手动返回一个对象
   
25 getter、setter方法

返回值类型 get get方法名 { 方法体 }

set set方法名(参数) { 方法体 }

26 debug模式

断言是有效的

服务扩展是有效的

debugging是有效的

flutter run运行

27 release模式

断言是无效的

服务扩展是无效的

debugging是无效的

flutter run —release

28 StatefulWidget的生命周期:

StatefulWidget的构造函数调用

StatefulWidget的createState调用

State的构造函数调用

State的initState调用

State的didChangeDependencies调用

State的build调用

State的dispose调用

29 try  catch  finally

num stringConvertNum(String str) {

  num result = 0;

  try {

    result = num.parse(str);

  } on FormatException catch (e) {

    print("发生Format异常 ${e.toString()}”);

  } finally {

    print("禁止程序崩溃");
  }

  print("result = $result”);

  return result;
}

30 子类和父类构造函数调用顺序 

先调用父类的构造方法,再调用子类的构造方法

31 Dart 中 num 类型分为 int 和 double ,没有float 类型。

Dart 中 if 等语句只支持 bool 类型

32 强类型语言

Dart属于是强类型语言,但可以用var来声明变量,Dart会自推导出数据类型。

var 实际上是编译期的“语法糖”。 

dynamic表示动态类型,被编译后实际是一个object类型,在编译期间不进行任何的类型检查,而是在运行期进行类型检查。

33 Dart中一切都是对象

在Dart中一切都是对象,所有的对象都继承自Object。

Dart是强类型语言,但可以用var或dynamic来声明一个变量,Dart会自动推断其数据类型。
 
Dart没有public protected private等关键字,如果某个变量以下划线(_)开头,代表这个变量在库中是私有的。

34 Dart语言的特性:

a:Dart的语法清晰明了,工具简单但功能强大。

b:容易上手,充分吸收了高级语言特性

c:响应式编程

d:执行速度快,Dart提供提前优化编译,在移动设备和Web上快速启动。

e:易于移植,Dart可编译成 ARM 和 X86 代码,这样Dart移动应用程序可以在 iOS、Android 和其他地方运行。

35 WidgetsBinding.instance.addPostFrameCallback

WidgetsBinding.instance.addPostFrameCallback(_onAfterRendering);

addPostFrameCallback 是 StatefulWidget 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用,

36 Dart的消息机制

Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。 

入口函数 main() 执行完后,消息循环机制便启动了。

首先会按照先进先出的顺序逐个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。

37 判断

final Brightness brightness1 = ThemeData.estimateBrightnessForColor(Colors.white);

Brightness.light

Brightness.dark

38 key

每个Widget都有唯一标识key,

如果key作为参数传入Widget里面,则会根据指定的名字生成key

在有些场景下需要保存key,并且通过key访问该Widget

可以通过GlobalKey、LocalKey、UniqueKey或ObjectKey进行保存

使用场景:复制操作,刷新组件

39 WidgetsBinding.instance.addPostFrameCallback

addPostFrameCallback 是StatefulWidget 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用。

addPostFrameCallback 的使用方法是在 initState 里添加回调:

void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) => {});
}

使用这个方法就可以在判断渲染完成,并获取到元素的大小。

40 StatefulWidget - 生命周期

1 构造函数

2 initState

3 didChangeDependencies

4 build

5 addPostFrameCallback

6 (组件状态改变)didUpdateWidget

7 deactivate

8 dispose

showModalBottomSheet系统弹框

41 StatelessWidget - 生命周期

1 构造函数初始化

2 提供build渲染

build 是用来创建 Widget 的,但因为 build 在每次界面刷新的时候都会调用,

所以不要在 build 里写业务逻辑,可以把业务逻辑写到你的 StatelessWidget 的构造函数里。


无状态的Widget

无法提供setState修改组件的状态

内部属性应声明为final,防止意外发生改变

42 App的生命周期

didChangeAppLifecycleState App生命周期发生变化

  切换后台:

  AppLifecycleState.inactive -> AppLifecycleState.paused
  
  @override
  void didChangeAppLifecycleState(AppLifecycleState state){
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
      // app退到后台后, 刷新状态
    }
  }

  切换前台:

  AppLifecycleState.inactive -> AppLifecycleState.resumed -> build

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // app显示后, 刷新状态
    if (state == AppLifecycleState.resumed) {
      // 刷新代码
    }
  }

43 组件移除

页面销毁的时候会依次执行:

deactivate : State对象从树中被移除时

dispose: State对象从树中被永久移除时调用;通常在此回调中释放资源

44 GestureDetector处理手势操作

HitTestBehavior.opaque 自己处理事件

 HitTestBehavior.deferToChild child处理事件


HitTestBehavior.translucent 自己和child都可以接收事件

45 时间戳获取

final int timestamp = DateTime.now().millisecondsSinceEpoch;

46 捕获Flutter framework异常

FlutterError.onError = (FlutterErrorDetails details) {


  LogPrint.d("捕获Flutter framework异常 ${details.exception}");


  Zone.current.handleUncaughtError(details.exception, details.stack!);
};

在2022年5月5日 上午9:35:36出现冲突的修改:
1 mounted:判断页面是否被释放,如果释放了就不进行渲染

if (mounted) {
  setState(() {
  });
}


2 GlobalKey的使用:

final GlobalKey<_UserInfoItemState> _globalKey = GlobalKey();

final String? userName = _globalKey.currentState?.widget.userName;

final String? userPhone = _globalKey.currentState?.userPhone;

3 安卓设备启动图片的大小

mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
320*480
480*800
720*1280
1080*1920
3840*2160
4 断言assert 

如果assert 的判断为true, 则继续执行下面的语句。反之抛出一个异常。

5 计算Text内容高度TextPainter

  double get descInfoHeight {
    final TextPainter painter = TextPainter(
      locale: WidgetsBinding.instance!.window.locale,
      maxLines: 2,
      textDirection: TextDirection.ltr,
      text: TextSpan(
        text: "",
        style: TextStyle(
          color: const Color(0xFF666666),
          fontSize: 14.sp,
          fontWeight: FontWeight.w500,
        ),
      ),
    );
    painter.layout(maxWidth: 170.w);
    return painter.height;
  }

6 计算item内容高度

  void calculateContentHeight() {
    Future<void>.delayed(const Duration(), () {
      if (!mounted) {
        return;
      }
      final RenderBox renderBox = context.findRenderObject() as RenderBox;
      print("width = ${renderBox.size.width}, height = ${renderBox.size.height}");
    });
  }

7 const和final

const:赋值的内容必须在编译时已经确定

final:赋值时,可以动态获取,赋值的内容在运行时已经确定

8 dynamic和Object

dynamic调用方法时,编译不会报错,运行时存在安全隐患

Object类型,调用方法时,编译会报错

9 Dart语法:

Dart是单线程的

 Dart中的函数不支持方法重载

设置高斯模糊 ImageFiltered


 SizeBox 设置水平方向、垂直方向的间距


用三个单引号表示多行字符串 '''         ‘’'




10 Set

集合类型Set:元素无序,不重复

11 ??=  赋值操作 
    
当变量有值,使用自己的值

当变量为null,使用后面的内容进行赋值
    
12 级联语法:

final p2 = Person()
           ..name = "why"
           ..run()
           ..eat()
           ..swim();

final p1 = Person();
p1.name = 'why’;
p1.run();
p1.eat();
p1.swim();
  
13 await

await 关键字必须在 async 函数内部使用

14 设置头像圆角

CircleAvatar
    
ClipOval

ClipRRect
    
Container + BoxDecoration + DecorationImage

15 CustomScrollView

slivers
    SliverAppBar
    SliverGrid
    SliverList

16  检测左上角的返回操作
  
外层包装一层WillPopScope,实现onWillPop方法

 返回为true: 使用系统提供的返回方法

返回为false:自定义返回方法
   
17 Icon 字体图标和图片图标

字体图标矢量图放大后不会失真

字体图标可以设置颜色

字体图标很多时,占据空间较小

18 build方法的执行时机:

Widget build(BuildContext context)

返回界面进行渲染的Widget

当Widget第一次被创建;当父Widget发生改变,子Widget会被重新构建


22 抽象类

关键字修饰:abstract
    
抽象类不能初始化
 
抽象类中的抽象方法必须被子类实现
  
抽象类中已经实现的方法可以不被子类重写
    
23 常量构造方法

const 修饰

常量构造方法的类中,所有成员变量必须是final修饰
    
24 工厂构造方法

 factory关键字修饰
    
可以手动返回一个对象
   
25 getter、setter方法

返回值类型 get get方法名 { 方法体 }

set set方法名(参数) { 方法体 }

26 debug模式

断言是有效的

服务扩展是有效的

debugging是有效的

运行:flutter run

27 release模式

断言是无效的

服务扩展是无效的

debugging是无效的

flutter run —release

28 StatefulWidget的生命周期:

StatefulWidget的构造函数调用

StatefulWidget的createState调用

State的构造函数调用

State的initState调用

State的didChangeDependencies调用

State的build调用

State的dispose调用

29 try  catch  finally

num stringConvertNum(String str) {

  num result = 0;

  try {

    result = num.parse(str);

  } on FormatException catch (e) {

    print("发生Format异常 ${e.toString()}”);

  } finally {

    print("禁止程序崩溃");
  }

  print("result = $result”);

  return result;
}

30 子类和父类构造函数调用顺序 

先调用父类的构造方法,再调用子类的构造方法

31 Dart 中 num 类型分为 int 和 double ,没有float 类型。

Dart 中 if 等语句只支持 bool 类型

32 强类型语言

Dart属于是强类型语言,但可以用var来声明变量,Dart会自推导出数据类型。

var 实际上是编译期的“语法糖”。 

dynamic表示动态类型,被编译后实际是一个object类型,在编译期间不进行任何的类型检查,而是在运行期进行类型检查。

33 Dart中一切都是对象

在Dart中一切都是对象,所有的对象都继承自Object。
 
Dart没有public protected private等关键字,如果某个变量以下划线(_)开头,代表这个变量在库中是私有的。

34 Dart语言的特性:

a:Dart的语法清晰明了,工具简单但功能强大。

b:容易上手,充分吸收了高级语言特性

c:响应式编程

d:执行速度快,Dart提供提前优化编译,在移动设备和Web上快速启动。

e:易于移植,Dart可编译成 ARM 和 X86 代码,这样Dart移动应用程序可以在 iOS、Android 和其他地方运行。

35 WidgetsBinding.instance.addPostFrameCallback

WidgetsBinding.instance.addPostFrameCallback(_onAfterRendering);

addPostFrameCallback 是 StatefulWidget 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用,

36 Dart的消息机制

Dart 在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是“微任务队列” microtask queue,另一个叫做“事件队列” event queue。 

入口函数 main() 执行完后,消息循环机制便启动了。

首先会按照先进先出的顺序逐个执行微任务队列中的任务,当所有微任务队列执行完后便开始执行事件队列中的任务,事件任务执行完毕后再去执行微任务,如此循环往复,生生不息。

37 判断

final Brightness brightness1 = ThemeData.estimateBrightnessForColor(Colors.white);

Brightness.light

Brightness.dark

38 key

每个Widget都有唯一标识key,

如果key作为参数传入Widget里面,则会根据指定的名字生成key

在有些场景下需要保存key,并且通过key访问该Widget

可以通过GlobalKey、LocalKey、UniqueKey或ObjectKey进行保存

使用场景:复制操作,刷新组件

39 WidgetsBinding.instance.addPostFrameCallback

addPostFrameCallback 是StatefulWidget 渲染结束的回调,只会被调用一次,之后 StatefulWidget 需要刷新 UI 也不会被调用。

addPostFrameCallback 的使用方法是在 initState 里添加回调:

void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) => {});
}

使用这个方法就可以在判断渲染完成,并获取到元素的大小。

40 StatefulWidget - 生命周期

1 构造函数

2 initState

3 didChangeDependencies

4 build

5 addPostFrameCallback

6 (组件状态改变)didUpdateWidget

7 deactivate

8 dispose

41 StatelessWidget - 生命周期

1 构造函数初始化

2 提供build渲染

build 是用来创建 Widget 的,但因为 build 在每次界面刷新的时候都会调用,

所以不要在 build 里写业务逻辑,可以把业务逻辑写到你的 StatelessWidget 的构造函数里。

无状态的Widget

无法提供setState修改组件的状态

内部属性应声明为final,防止意外发生改变

42 App的生命周期

didChangeAppLifecycleState App生命周期发生变化

  切换后台:

  AppLifecycleState.inactive -> AppLifecycleState.paused
  
  @override
  void didChangeAppLifecycleState(AppLifecycleState state){
    super.didChangeAppLifecycleState(state);
    // app退到后台
    if (state == AppLifecycleState.paused) {
    }
  }

  切换前台:

  AppLifecycleState.inactive -> AppLifecycleState.resumed

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // app回到前台
    if (state == AppLifecycleState.resumed) {
    }
  }

43 组件移除

页面销毁的时候会依次执行:

deactivate : State对象从树中被移除时

dispose: State对象从树中被永久移除时调用;通常在此回调中释放资源

44 GestureDetector处理手势操作

HitTestBehavior.opaque 自己处理事件

 HitTestBehavior.deferToChild child处理事件


HitTestBehavior.translucent 自己和child都可以接收事件

45 时间戳获取

final int timestamp = DateTime.now().millisecondsSinceEpoch;

46 捕获Flutter framework异常

FlutterError.onError = (FlutterErrorDetails details) {

  LogPrint.d("捕获Flutter framework异常 ${details.exception}");

  Zone.current.handleUncaughtError(details.exception, details.stack!);
};

47 Flutter创建module

flutter create -t module flutter_module

48 widget 树的 root 节点

runApp()方法中的 Widget。

49 编译模式

Flutter 的 Debug 下是 JIT 模式,release 下是 AOT 模式。

50 AutomaticKeepAliveClientMixin

Flutter 中可以通过 mixin AutomaticKeepAliveClientMixin ,

然后重写 wantKeepAlive 保持住页面,build 中调用super.build 。

51 如何实现点击空白区域收起键盘?

FocusScope.of(context).requestFocus(FocusNode());

52 如何统一管理错误页面?

// 自定义错误页面
ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails) {
  return const Text("data");
};

53 Dart 属于是强类型语言

Dart 属于是强类型语言 ,但可以用 var 来声明变量,

Dart 会自推导出数据类型,var 实际上是编译期的“语法糖”。

dynamic 表示动态类型,被编译后,实际是一个 object 类型,

在编译期间不进行任何的类型检查,而是在运行期进行类型检查。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容