フラッターを部分的にリフレッシュするいくつかの方法
1 つ目: GlobalKey を使用する
親コンポーネントで宣言されている
GlobalKey<_部分更新オブジェクト タイプ State> textKey = GlobalKey();
textKey.currentState.部分更新メソッド();
二番目
使用: StatefulBuilder
三番目
StreamBuilder + StreamController FutureBuilder と StreamBuilderを使用する
3 番目のタイプ: プロバイダー (非同期通信も)
ChangeNotifier + ChangeNotifierProvider
4 番目のタイプ (これも非同期通信): Flutter ValueNotifier 非同期通信、ValueListenableBuilder bzdww
ValueNotifier + ValueListenableBuilder
1 つ目: GlobalKey を使用する
globalkey は要素を一意に定義するため、その要素に関連付けられた他のオブジェクト (buildContext、state など) にアクセスできるようになります。
使用シナリオ: key.currentState を通じてその状態オブジェクトを取得し、その onPressed メソッドを呼び出すことができます。
//请求刷新
setState((){
});
#State<T extends StatefulWidget>
@override
Widget build(BuildContext context) {
//构建新的Widget
return new Text(_text);
}
次に、build メソッドで return new Text(_text) を公開できれば、一般的な部分更新ウィジェットを実装できます。
実行計画
- インターフェイス コールバックは、新しい Text(_text) を返します。公開されています:
typedef関数で実装
//定义函数别名
typedef BuildWidget = Widget Function();
関数エイリアス BuildWidget をパラメータとして State.build メソッドに渡します。
完全なコード
import 'package:flutter/material.dart';
//封装 通用局部刷新工具类
//定义函数别名
typedef BuildWidget = Widget Function();
class PartRefreshWidget extends StatefulWidget {
PartRefreshWidget(Key key, this._child): super(key: key);
BuildWidget _child;
@override
State<StatefulWidget> createState() {
return PartRefreshWidgetState(_child);
}
}
class PartRefreshWidgetState extends State<PartRefreshWidget> {
BuildWidget child;
PartRefreshWidgetState(this.child);
@override
Widget build(BuildContext context) {
return child.call();
}
void update() {
print('update');
setState(() {
});
}
}
使用:
import 'package:flutter/material.dart';
import 'PartRefreshWidget.dart';
class GlobalKeyDemo extends StatefulWidget {
@override
_GlobalKeyDemoState createState() => _GlobalKeyDemoState();
}
class _GlobalKeyDemoState extends State<GlobalKeyDemo> {
int _count = 0;
//使用1 创建GlobalKey
GlobalKey<PartRefreshWidgetState> globalKey = new GlobalKey();
@override
Widget build(BuildContext context) {
print('----------------build');
return Scaffold(
appBar: AppBar(
title: Text("inheritedWidget"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//使用2 创建通用局部刷新widget
PartRefreshWidget(globalKey, () {
///创建需要局部刷新的widget
return Text(
'变化的:$_count',
style: TextStyle(color: Colors.green),
);
}),
Text('不变的: $_count'),
RaisedButton(
onPressed: () {
//点击
_count++;
//使用3调用刷新方法
globalKey.currentState.update();
},
),
],
),
)
);
}
}
転載:https://blog.csdn.net/jdsjlzx/article/details/123560075
2 番目: StatefulBuilder を使用します。
使用シナリオ:
複数選択と単一選択
単一選択の場合は、1つ選択するだけで結果を直接返すことができるため、下部のポップアップウィンドウ自体の状態管理は必要ありません。ただし、複数選択の場合は、現在選択されているオプションを知る必要があります。オプションがクリックされたときは、そのオプションが保存される必要があります。再度クリックされたときは、このオプションがクリアされる必要があります。同時に、インターフェイスは同期して更新する必要があるため、状態管理が必要になります。
内部で使用される実装。
StatefulBuilder
Flutter にはステートフルコンポーネントを構築するメソッドと状態更新メソッドを提供する クラスが用意されており builder
、その中で状態管理が完結します。
この builder
メソッドでは、実際には、setState
対応する状態コンポーネントのsetState
対応するメソッド であり、この状態はStatefulBuilder
、生成されたコンポーネントの状態を制御するために使用されます。この方法は フック関数の使用法React
に 似ています。useState
使用されるコアコード:
class DemoStatefulBuilderPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//状态构建器
body: buildStatefulBuilder(),
);
}
}
int _count = 0;
StatefulBuilder buildStatefulBuilder() {
return StatefulBuilder(
//构建状态改变的Widget
builder: (BuildContext context, void Function(void Function()) setState) {
//居中
return Center(
//手势识别
child: GestureDetector(
child: Text("早起的年轻人 $_count"),
//单击事件
onTap: () {
//刷新当前 StatefulBuilder 中的状态
setState(() {
_count++;
});
},
),
);
},
);
}
3 番目は FutureBuilder と StreamBuilder を使用します
使用シナリオ: 非同期 UI 更新
多くの場合、UI を動的に更新するために非同期データに依存します。たとえば、ページを開くときは、最初にインターネットからデータを取得し、データ取得プロセス中に読み込みボックスを表示する必要があります。データが取得されました もう一度ページをレンダリングしましょう; 別の例として、ストリーム (ファイル ストリーム、インターネット データ受信ストリームなど) の進行状況を表示したい場合があります。もちろん、上記の機能はStatefulWidgetでも完全に実現できます。ただし、実際の開発では UI を更新するために非同期データに依存することが非常に一般的であり、StatefulWidget のコントロール ツリーが大きい場合、プロパティを更新するとツリー全体が再構築され、パフォーマンスが消費されるため、Flutter は特に 2 つの機能を提供します。コンポーネント、FutureBuilder および SteamBuilder この機能を迅速に実現します。
FutureBuilderの使用
const FutureBuilder({
Key key,
this.future, //获取数据的方法 获取用户异步处理获得数据的代码
this.initialData, //初始的默认数据 初始化数据加载
@required this.builder //数据快照 回调函数,暴露异步处理中的快照。这个是我们构建组件的主要组成。 主要来看一下它的构造函数:
}) : assert(builder != null),
super(key: key);
class _MyHomePageState extends State<MyHomePage> {
Future<String> mockNetworkData() async {
return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
FutureBuilder(
future: mockNetworkData(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasError){
// 请求失败,显示错误
return Text("Error: ${snapshot.error}");
}else {
// 请求成功,显示数据
return Text("Contents: ${snapshot.data}");
}
}else {
return CircularProgressIndicator();
}
}),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
SteamBuilderの使用
class _MyHomePageState extends State<MyHomePage> {
Stream<int> counter(){
return Stream.periodic(Duration(seconds: 1), (i){
return i;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder(
stream: counter(),
builder: (BuildContext context, AsyncSnapshot<int> snapshot){
if(snapshot.hasError){
return Text("Error: ${snapshot.error}");
}
switch (snapshot.connectionState){
case ConnectionState.none:
return Text("没有Stream");
case ConnectionState.waiting:
return Text("等待数据、、、");
case ConnectionState.active:
return Text("active: ${snapshot.data}");
case ConnectionState.done:
return Text("Stream已关闭");
}
return null;
}),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
StreamBuilder と StreamController の詳細な使用法: https://blog.csdn.net/u010194271/article/details/128024208