欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

flutter泛型,float型

flutter-動(dòng)畫

1.動(dòng)畫原理:在一段時(shí)間內(nèi)快速的多次改變UI外觀,由于人眼會(huì)產(chǎn)生視覺暫留所以最終看到的就是一個(gè)連續(xù)的動(dòng)畫。

成都創(chuàng)新互聯(lián)公司是一家專業(yè)從事成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)的品牌網(wǎng)絡(luò)公司。如今是成都地區(qū)具影響力的網(wǎng)站設(shè)計(jì)公司,作為專業(yè)的成都網(wǎng)站建設(shè)公司,成都創(chuàng)新互聯(lián)公司依托強(qiáng)大的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)及網(wǎng)站設(shè)計(jì)開發(fā)服務(wù)!

UI的一次改變稱為一個(gè)動(dòng)畫幀,對(duì)應(yīng)一次屏幕刷新。

FPS:幀率,每秒的動(dòng)畫幀數(shù)。

flutter動(dòng)畫分為兩類:

常見動(dòng)畫模式:

是一個(gè)抽象類,主要的功能是保存動(dòng)畫的值和狀態(tài)。常用的一個(gè)Animation類是Animation double ,是一個(gè)在一段時(shí)間內(nèi)依次生成一個(gè)區(qū)間之間的值的類,可以是線性或者曲線或者其他。

可以生成除double之外的其他類型值,如:Animation Color 或 Animation Size 。

是一個(gè)動(dòng)畫控制器,控制動(dòng)畫的播放狀態(tài),在屏幕刷新的每一幀,就會(huì)生成一個(gè)新的值。

包含動(dòng)畫的啟動(dòng)forward()、停止stop() 、反向播放 reverse()等方法,在給定的時(shí)間段內(nèi)線性的生成從0.0到1.0(默認(rèn)區(qū)間)的數(shù)字。

curve:描述動(dòng)畫的曲線過程。

curvedAnimation:指定動(dòng)畫的曲線。

常用Curve:

繼承自Animatable T ,表示的就是一個(gè) Animation 對(duì)象的取值范圍,只需要設(shè)置開始和結(jié)束的邊界值(值也支持泛型)。 它唯一的工作就是定義輸入范圍到輸出范圍的映射。

例如,Tween可能會(huì)生成從紅到藍(lán)之間的色值,或者從0到255。

Tween.animate:返回一個(gè)Animation。

映射過程:

1). Tween.animation通過傳入 aniamtionController 獲得一個(gè)_AnimatedEvaluation 類型的 animation 對(duì)象(基類為 Animation), 并且將 aniamtionController 和 Tween 對(duì)象傳入了 _AnimatedEvaluation 對(duì)象。

2). animation.value方法即是調(diào)用 _evaluatable.evaluate(parent)方法, 而 _evaluatable 和 parent 分別為 Tween 對(duì)象和 AnimationController 對(duì)象。

3). 這里的 animation 其實(shí)就是前面的 AnimationController 對(duì)象, transform 方法里面的 animation.value則就是 AnimationController 線性生成的 0.0~1.0 直接的值。 在 lerp 方法里面我們可以看到這個(gè) 0.0~1.0 的值被映射到了 begin 和 end 范圍內(nèi)了。

接收一個(gè)TickerProvider類型的對(duì)象,它的主要職責(zé)是創(chuàng)建Ticker。

防止屏幕外動(dòng)畫消耗資源。

[圖片上傳失敗...(image-115b94-1636441483468)]

過程:

回調(diào):

不使用addListener()和setState()來給widget添加動(dòng)畫。

使用AnimatedWidget,將widget分離出來,創(chuàng)建一個(gè)可重用動(dòng)畫的widget,AnimatedWidget中會(huì)自動(dòng)調(diào)用addListener()和setState()

AnimatedModalBarrier、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition

如何渲染過渡,把渲染過程也抽象出來:

AnimatedBuilder的示例包括: BottomSheet、 PopupMenu、ProgressIndicator、RefreshIndicator、Scaffold、SnackBar、TabBar。

MaterialPageRoute:平臺(tái)風(fēng)格一致的路由切換動(dòng)畫

CupertinoPageRoute:左右切換風(fēng)格

自定義:PageRouteBuilder

1.要?jiǎng)?chuàng)建交織動(dòng)畫,需要使用多個(gè)動(dòng)畫對(duì)象(Animation)。

2.一個(gè)AnimationController控制所有的動(dòng)畫對(duì)象。

3.給每一個(gè)動(dòng)畫對(duì)象指定時(shí)間間隔(Interval)

可以同時(shí)對(duì)其新、舊子元素添加顯示、隱藏動(dòng)畫.

當(dāng)AnimatedSwitcher的child發(fā)生變化時(shí)(類型或Key不同),舊child會(huì)執(zhí)行隱藏動(dòng)畫,新child會(huì)執(zhí)行執(zhí)行顯示動(dòng)畫。

希望大家支持一下,感謝

Flutter 小技巧之優(yōu)化你使用的 BuildContext

Flutter 里的 BuildContext 相信大家都不會(huì)陌生,雖然它叫 Context,但是它實(shí)際是 Element 的抽象對(duì)象,而在 Flutter 里,它主要來自于 ComponentElement 。

關(guān)于 ComponentElement 可以簡(jiǎn)單介紹一下,在 Flutter 里根據(jù) Element 可以簡(jiǎn)單地被歸納為兩類:

所以一般情況下,我們?cè)? build 方法或者 State 里獲取到的 BuildContext 其實(shí)就是 ComponentElement 。

那使用 BuildContext 有什么需要注意的問題 ?

首先如下代碼所示,在該例子里當(dāng)用戶點(diǎn)擊 FloatingActionButton 的時(shí)候,代碼里做了一個(gè) 2秒的延遲,然后才調(diào)用 pop 退出當(dāng)前頁面。

正常情況下是不會(huì)有什么問題,但是當(dāng)用戶在點(diǎn)擊了 FloatingActionButton 之后,又馬上點(diǎn)擊了 AppBar 返回退出應(yīng)用,這時(shí)候就會(huì)出現(xiàn)以下的錯(cuò)誤提示。

可以看到此時(shí) log 說,Widget 對(duì)應(yīng)的 Element 已經(jīng)不在了,因?yàn)樵? Navigator.of(context) 被調(diào)用時(shí), context 對(duì)應(yīng)的 Element 已經(jīng)隨著我們的退出銷毀。

一般情況下處理這個(gè)問題也很簡(jiǎn)單, 那就是增加 mounted 判斷,通過 mounted 判斷就可以避免上述的錯(cuò)誤 。

上面代碼里的 mounted 標(biāo)識(shí)位來自于 State , 因?yàn)? State 是依附于 Element 創(chuàng)建,所以它可以感知 Element 的生命周期 ,例如 mounted 就是判斷 _element != null; 。

那么到這里我們收獲了一個(gè)小技巧: 使用 BuildContext 時(shí),在必須時(shí)我們需要通過 mounted 來保證它的有效性 。

那么單純使用 mounted 就可以滿足 context 優(yōu)化的要求了嗎 ?

如下代碼所示,在這個(gè)例子里:

由于在 5 秒之內(nèi),Item 被劃出了屏幕,所以對(duì)應(yīng)的 Elment 其實(shí)是被釋放了,從而由于 mounted 判斷, SnackBar 不會(huì)被彈出。

那如果假設(shè)需要在開發(fā)時(shí)展示點(diǎn)擊數(shù)據(jù)上報(bào)的結(jié)果,也就是 Item 被釋放了還需要彈出,這時(shí)候需要如何處理 ?

我們知道不管是 ScaffoldMessenger.of(context) 還是 Navigator.of(context) ,它本質(zhì)還是通過 context 去往上查找對(duì)應(yīng)的 InheritedWidget 泛型,所以其實(shí)我們可以提前獲取。

所以,如下代碼所示,在 Future.delayed 之前我們就通過 ScaffoldMessenger.of(context); 獲取到 sm 對(duì)象,之后就算你直接退出當(dāng)前的列表頁面,5秒過后 SnackBar 也能正常彈出。

為什么頁面銷毀了,但是 SnackBar 還能正常彈出 ?

因?yàn)榇藭r(shí)通過 of(context); 獲取到的 ScaffoldMessenger 是存在 MaterialApp 里,所以就算頁面銷毀了也不影響 SnackBar 的執(zhí)行。

但是如果我們修改例子,如下代碼所示,在 Scaffold 上面多嵌套一個(gè) ScaffoldMessenger ,這時(shí)候在 Item 里通過 ScaffoldMessenger.of(context) 獲取到的就會(huì)是當(dāng)前頁面下的 ScaffoldMessenger 。

這種情況下我們只能保證Item 不可見的時(shí)候 SnackBar 還能正常彈出, 而如果這時(shí)候我們直接退出頁面,還是會(huì)出現(xiàn)以下的錯(cuò)誤提示,因?yàn)? ScaffoldMessenger 也被銷毀了 。

所以到這里我們收獲第二個(gè)小技巧: 在異步操作里使用 of(context) ,可以提前獲取,之后再做異步操作,這樣可以盡量保證流程可以完整執(zhí)行 。

既然我們說到通過 of(context) 去獲取上層共享往下共享的 InheritedWidget ,那在哪里獲取就比較好 ?

還記得前面的 log 嗎?在第一個(gè)例子出錯(cuò)時(shí),log 里就提示了一個(gè)方法,也就是 State 的 didChangeDependencies 方法。

為什么是官方會(huì)建議在這個(gè)方法里去調(diào)用 of(context) ?

首先前面我們一直說,通過 of(context) 獲取到的是 InheritedWidget ,而 當(dāng) InheritedWidget 發(fā)生改變時(shí),就是通過觸發(fā)綁定過的 Element 里 State 的 didChangeDependencies 來觸發(fā)更新, 所以在 didChangeDependencies 里調(diào)用 of(context) 有較好的因果關(guān)系 。

那我能在 initState 里提前調(diào)用嗎 ?

當(dāng)然不行,首先如果在 initState 直接調(diào)用如 ScaffoldMessenger.of(context).showSnackBar 方法,就會(huì)看到以下的錯(cuò)誤提示。

這是因?yàn)?Element 里會(huì)判斷此時(shí)的 _StateLifecycle 狀態(tài),如果此時(shí)是 _StateLifecycle.created 或者 _StateLifecycle.defunct ,也就是在 initState 和 dispose ,是不允許執(zhí)行 of(context) 操作。

當(dāng)然,如果你硬是想在 initState 下調(diào)用也行,增加一個(gè) Future 執(zhí)行就可以成功執(zhí)行

那我在 build 里直接調(diào)用不行嗎 ?

直接在 build 里調(diào)用肯定可以,雖然 build 會(huì)被比較頻繁執(zhí)行,但是 of(context) 操作其實(shí)就是在一個(gè) map 里通過 key - value 獲取泛型對(duì)象,所以對(duì)性能不會(huì)有太大的影響。

真正對(duì)性能有影響的是 of(context) 的綁定數(shù)量和獲取到對(duì)象之后的自定義邏輯 ,例如你通過 MediaQuery.of(context).size 獲取到屏幕大小之后,通過一系列復(fù)雜計(jì)算來定位你的控件。

例如上面這段代碼,可能會(huì)導(dǎo)致鍵盤在彈出的時(shí)候,雖然當(dāng)前頁面并沒有完全展示,但是也會(huì)導(dǎo)致你的控件不斷重新計(jì)算從而出現(xiàn)卡頓。

所以到這里我們又收獲了一個(gè)小技巧: 對(duì)于 of(context) 的相關(guān)操作邏輯,可以盡量放到 didChangeDependencies 里去處理 。

Flutter GetX基礎(chǔ)教程(十二):RxList、Rx([])、.obs對(duì)比分析

首先我們知道 GetX 組件里面 obs 狀態(tài)管理有三種創(chuàng)建屬性的方式,我們這里以 List 為例

視頻講解鏈接

我們聲明了一個(gè)類ListController 繼承自 GetxController ,用于屬性創(chuàng)建以及狀態(tài)通知的方法,首先我們用三種方式來創(chuàng)建屬性并且通過 convertToUpperCase 方法進(jìn)行對(duì)值的改變,然后我們通過調(diào)用 update()`方法來進(jìn)行數(shù)據(jù)更新,最后我們使用該屬性狀態(tài)的值,接下來我們看一下三種使用方式的對(duì)比。

import 'dart:convert';

import 'package:get/get.dart';

class ListController extends GetxController {

// 第一種

final listOne = RxListMap([

{

"name": "Jimi",

"age": 18

}

]);

// 第二種

final listTwo = RxList([

{

"name": "Jimi",

"age": 18

}

]);

// 第三種

final listThree = [{

"name": "Jimi",

"age": 18

}].obs;

void convertToUpperCase() {

listOne.value[0]["name"] = listOne.value.first["name"].toUpperCase();

listTwo.toList().first["name"] = listTwo.toList().first["name"].toString().toUpperCase();

listThree.toList().first["name"] = listTwo.toList().first["name"].toString().toUpperCase();

update();

}

}

我們?cè)陧撁嬷蝎@取狀態(tài)更新的值

import 'package:flutter/material.dart';

import 'package:flutter_getx_dvanced_example/ListController.dart';

import 'package:get/get.dart';

void main() {

runApp(MyApp());

}

class MyApp extends StatelessWidget {

ListController listController = Get.put(ListController());

@override

Widget build(BuildContext context) {

return GetMaterialApp(

title: "GetX",

home: Scaffold(

appBar: AppBar(

title: Text("GetX"),

),

body: Center(

child: Column(

mainAxisAlignment: MainAxisAlignment.center,

crossAxisAlignment: CrossAxisAlignment.center,

children: [

GetBuilderListController(

init: listController,

builder: (controller) {

return Text(

"我的名字是 {controller.listTwo.first['name']}",

style: TextStyle(color: Colors.green, fontSize: 30),

);

},

),

SizedBox(height: 20,),

GetBuilderListController(

init: listController,

builder: (controller) {

return Text(

"我的名字是 ${controller.listThree.first['name']}",

style: TextStyle(color: Colors.green, fontSize: 30),

);

},

),

SizedBox(height: 20,),

ElevatedButton(

onPressed: () {

listController.convertToUpperCase();

},

child: Text("轉(zhuǎn)換為大寫"))

],

),

),

),

);

}

}

/pre

|`

效果展示

RxT 繼承自 _RxImplT , _RxImplT 又繼承 RxNotifierT 并混合 RxObjectMixinT 類

RxImplT 它主要的作用是管理泛型的所有邏輯的。

RxObjectMixinT 它主要的作用是管理注冊(cè)到 GetX 和 Obx 的全局對(duì)象,比如 Widget 的 Rx 值

RxT 它主要的作用是將自定義模型類用Rx`來進(jìn)行包裝,

class RxT extends _RxImplT {

Rx(T initial) : super(initial);

@override

dynamic toJson() {

try {

return (value as dynamic)?.toJson();

} on Exception catch (_) {

throw '$T has not method [toJson]';

}

}

}

abstract class _RxImplT extends RxNotifierT with RxObjectMixinT {

_RxImpl(T initial) {

_value = initial;

}

void addError(Object error, [StackTrace? stackTrace]) {

subject.addError(error, stackTrace);

}

StreamR mapR(R mapper(T? data)) = stream.map(mapper);

void update(void fn(T? val)) {

fn(_value);

subject.add(_value);

}

void trigger(T v) {

var firstRebuild = this.firstRebuild;

value = v;

if (!firstRebuild) {

subject.add(v);

}

}

}

/pre

|`

RxListE 繼承自 ListMixinE 實(shí)現(xiàn)了 RxInterfaceListE 并混合了 NotifyManagerListE, RxObjectMixinListE

RxListE 它的主要作用是創(chuàng)建一個(gè)類似于 ListT 的一個(gè)列表

class RxListE extends ListMixinE

with NotifyManagerListE, RxObjectMixinListE

implements RxInterfaceListE {

RxList([ListE initial = const []]) {

_value = List.from(initial);

}

factory RxList.filled(int length, E fill, {bool growable = false}) {

return RxList(List.filled(length, fill, growable: growable));

}

factory RxList.empty({bool growable = false}) {

return RxList(List.empty(growable: growable));

}

/// Creates a list containing all [elements].

factory RxList.from(Iterable elements, {bool growable = true}) {

return RxList(List.from(elements, growable: growable));

}

/// Creates a list from [elements].

factory RxList.of(IterableE elements, {bool growable = true}) {

return RxList(List.of(elements, growable: growable));

}

/// Generates a list of values.

factory RxList.generate(int length, E generator(int index),

{bool growable = true}) {

return RxList(List.generate(length, generator, growable: growable));

}

/// Creates an unmodifiable list containing all [elements].

factory RxList.unmodifiable(Iterable elements) {

return RxList(List.unmodifiable(elements));

}

@override

IteratorE get iterator = value.iterator;

@override

void operator []=(int index, E val) {

_value[index] = val;

refresh();

}

/// Special override to push() element(s) in a reactive way

/// inside the List,

@override

RxListE operator +(IterableE val) {

addAll(val);

refresh();

return this;

}

@override

E operator [](int index) {

return value[index];

}

@override

void add(E item) {

_value.add(item);

refresh();

}

@override

void addAll(IterableE item) {

_value.addAll(item);

refresh();

}

@override

int get length = value.length;

@override

@protected

ListE get value {

RxInterface.proxy?.addListener(subject);

return _value;

}

@override

set length(int newLength) {

_value.length = newLength;

refresh();

}

@override

void insertAll(int index, IterableE iterable) {

_value.insertAll(index, iterable);

refresh();

}

@override

IterableE get reversed = value.reversed;

@override

IterableE where(bool Function(E) test) {

return value.where(test);

}

@override

IterableT whereTypeT() {

return value.whereTypeT();

}

@override

void sort([int compare(E a, E b)?]) {

_value.sort(compare);

refresh();

}

}

/pre

|`

當(dāng)我們?cè)谡{(diào)用 .obs 的時(shí)候其實(shí)內(nèi)部的實(shí)現(xiàn)源碼還是通過 RxListe(this) 進(jìn)行了一層包裝,設(shè)計(jì)這個(gè)主要的目的就是為了方便開發(fā)者進(jìn)行使用

ListExtensionE on ListE {

RxListE get obs = RxListE(this);

/// Add [item] to [ListE] only if [item] is not null.

void addNonNull(E item) {

if (item != null) add(item);

}

// /// Add [IterableE] to [ListE] only if [IterableE] is not null.

// void addAllNonNull(IterableE item) {

// if (item != null) addAll(item);

// }

/// Add [item] to ListE only if [condition] is true.

void addIf(dynamic condition, E item) {

if (condition is Condition) condition = condition();

if (condition is bool condition) add(item);

}

/// Adds [IterableE] to [ListE] only if [condition] is true.

void addAllIf(dynamic condition, IterableE items) {

if (condition is Condition) condition = condition();

if (condition is bool condition) addAll(items);

}

/// Replaces all existing items of this list with [item]

void assign(E item) {

// if (this is RxList) {

// (this as RxList)._value;

// }

}

/// Replaces all existing items of this list with [items]

void assignAll(IterableE items) {

// if (this is RxList) {

// (this as RxList)._value;

// }

clear();

addAll(items);

}

}

/pre

|`

我們對(duì) RxT([]) 、 RxListE 、 .obs 進(jìn)行了一個(gè)總結(jié),在我們平時(shí)的開發(fā)過程中建議大家使用 .obs 即可,因?yàn)檫@是最簡(jiǎn)單的方式。

FlutterJsonBeanFactory插件json使用

使用注解@JSONField

其中name: "list"的list就是后臺(tái)返回字段名稱,deserialize(默認(rèn)true)是否參與fromJson解析,serialize(默認(rèn)true)是否參與tojson,

比如包含如下json

可以解析出來list中map的所有字段,并且每個(gè)list的map字段不同或者為null問題有會(huì)做出處理

helper文件內(nèi)容

直接傳遞上面生成的entity就可以自動(dòng)根據(jù)map解析出對(duì)應(yīng)實(shí)例,并自動(dòng)賦值

網(wǎng)絡(luò)請(qǐng)求實(shí)例

dio請(qǐng)求部分

這些操作完成后自動(dòng)生成如下文件

@JSONField作用在Field時(shí),其name不僅定義了輸入key的名稱,為了防止后臺(tái)返回?cái)?shù)據(jù)不規(guī)范,但是flutter端需要按照駝峰命名

a_b_c_entity_helper.dart類提供了eitity類的tojson和fromjson代理方法

json_convert_content.dart提供了json_convert_content.dart.fromJsonAsT方法 根據(jù)泛型來解析json成對(duì)象

Flutter進(jìn)階篇(4)-- Flutter的Future異步詳解

本文首發(fā)在公眾號(hào) Flutter那些事 ,歡迎大家多多關(guān)注。

工具安裝:

Flutter基礎(chǔ)篇:

Flutter進(jìn)階篇:

Dart語法基礎(chǔ)篇:

Dart語法進(jìn)階篇:

說明:本文中的所有函數(shù)的引用在 main 函數(shù)中:

這里的執(zhí)行結(jié)果是:

Futue直接new就可以了。我這里沒有具體的返回?cái)?shù)據(jù),所以就用匿名函數(shù)代替了, Future future = new Future(() = null); 相當(dāng)于 FutureNull future = new Future(() = null); 泛型如果為null可以省略不寫,為了便于維護(hù)和管理,開發(fā)中建議加上泛型。

輸出結(jié)果是:

future里面有幾個(gè)函數(shù):

then :異步操作邏輯在這里寫。

whenComplete :異步完成時(shí)的回調(diào)。

catchError :捕獲異常或者異步出錯(cuò)時(shí)的回調(diào)。

因?yàn)檫@里面的異步操作過程中沒有遇到什么錯(cuò)誤,所以catchError回調(diào)不會(huì)調(diào)用。

我們可以看到執(zhí)行結(jié)果是:

我們可以看到輸出結(jié)果是: 2 1 3 和我們創(chuàng)建Future對(duì)象的先后順序完全一致。

我們可以看到結(jié)果為 1 2 3 ,和我們調(diào)用then的先后順序無關(guān)。:

當(dāng)then回調(diào)函數(shù)里面還有then回調(diào)的時(shí)候,這時(shí)候的流程跟前面就不太一樣了,也是一個(gè)大坑,也是面試經(jīng)常會(huì)被問到的一個(gè)知識(shí)點(diǎn)。

我們可以看到執(zhí)行結(jié)果如下:

結(jié)果還是一樣的:

運(yùn)行結(jié)果是:

這里再次證明了上面我的猜想: 執(zhí)行順序和和創(chuàng)建Future的先后順序有關(guān),如果有多個(gè)then嵌套執(zhí)行,先執(zhí)行外面的then,然后執(zhí)行里面的then。

執(zhí)行結(jié)果如下,我們可以看到then內(nèi)部創(chuàng)建的Future要等到then執(zhí)行完了,最后再去執(zhí)行的:

根據(jù)上文總結(jié)的特點(diǎn),我們可以不用運(yùn)行也能推斷出輸出結(jié)果:

為了驗(yàn)證我們的猜想,我們打印一下輸出結(jié)果,果然我們的證明是正確的。

我們重點(diǎn)看看 then函數(shù)的文檔說明:

then 注冊(cè)在 Future 完成時(shí)調(diào)用的回調(diào)。

當(dāng)這個(gè) Future 用一個(gè) value 完成時(shí),將使用該值調(diào)用 onValue 回調(diào)。

如果 Future 已經(jīng)完成,則不會(huì)立即調(diào)用回調(diào),而是將在稍后的 microtask(微任務(wù)) 中調(diào)度。

如果回調(diào)返回 Future ,那么 then 返回的 future 將與 callback 返回的 future 結(jié)果相同。

onError 回調(diào)必須接受一個(gè)參數(shù)或兩個(gè)參數(shù),后者是[StackTrace]。

如果 onError 接受兩個(gè)參數(shù),則使用錯(cuò)誤和堆棧跟蹤時(shí)調(diào)用它,否則僅使用錯(cuò)誤對(duì)象時(shí)候調(diào)用它。

onError 回調(diào)必須返回一個(gè)可用于完成返回的future的值或future,因此它必須是可賦值給 FutureOr R 的東西。

返回一個(gè)新的 Future ,該 Future 是通過調(diào)用 onValue (如果這個(gè)Future是通過一個(gè)value完成的)或' onError (如果這個(gè)Future是通過一個(gè)error完成的)的結(jié)果完成的。

如果調(diào)用的回調(diào)拋出異常,返回的 future 將使用拋出的錯(cuò)誤和錯(cuò)誤的堆棧跟蹤完成。在 onError 的情況下,如果拋出的異常與 onError 的錯(cuò)誤參數(shù)“相同(identical)”,則視為重新拋出,并使用原始堆棧跟蹤替代

如果回調(diào)返回 Future ,則 then 返回的 Future 將以與回調(diào)返回的 Future 相同的結(jié)果完成。

如果未給出 onError ,并且后續(xù)程序走了剛出現(xiàn)了錯(cuò)誤,則錯(cuò)誤將直接轉(zhuǎn)發(fā)給返回的 Future 。

在大多數(shù)情況下,單獨(dú)使用 catchError 更可讀,可能使用 test 參數(shù),而不是在單個(gè) then 調(diào)用中同時(shí)處理 value 和 error 。

請(qǐng)注意,在添加監(jiān)聽器(listener)之前, future 不會(huì)延遲報(bào)告錯(cuò)誤。如果第一個(gè) then 或 catchError 調(diào)用在 future 完成后發(fā)生 error ,那么 error 將報(bào)告為未處理的錯(cuò)誤。

Flutter 熱重載未生效

將枚舉類型更改為常規(guī)類或?qū)⒊R?guī)類更改為枚舉類型時(shí),熱重載(r)不起作用。 需要hot restart(cmd + shift + r)

修改泛型類型聲明后,熱重裝將無法工作。 例如,以下操作將無效:

Widget 快速替換 、 包裝 、 移動(dòng) 、 刪除 、 抽取成變量 、 抽取成方法

焦點(diǎn)放到相應(yīng)的widget上, 然后 cmd + . 如果提示沒有相關(guān)操作,多試幾次

網(wǎng)站欄目:flutter泛型,float型
新聞來源:http://chinadenli.net/article10/dsggjdo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)外貿(mào)網(wǎng)站建設(shè)網(wǎng)站策劃網(wǎng)站內(nèi)鏈小程序開發(fā)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司