Flutter實現區域性重新整理
阿新 • • 發佈:2020-07-15
在Flutter中,如果我們想要更新頁面中的某個widget的狀態的話,一般會使用setState方法重走build方法來重新整理。當頁面佈局複雜的時候,這樣肯定是不行的。
下面提供了兩種區域性重新整理的方式,通過provider和StreamBuilder來實現區域性重新整理
1、通過provider重新整理
首先在pubspec.yaml中新增provider依賴
# provider provider: ^3.1.0
下面通過provider來實現一個傳送驗證碼的案例。
建立一個TimerModel檔案
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:rxdart/rxdart.dart'; class TimerModel extends ChangeNotifier{ StreamSubscription _subscription; int _count = 0;///當前計數 int get count => 10 - _count;///剩餘時間 _setCount(){ _count++; notifyListeners(); } startTimer(){ _count = 0; _subscription = Observable.periodic(Duration(seconds: 1)) .startWith(10) .take(10) .listen((t){ _setCount(); }); } @override void dispose() { _subscription?.cancel(); super.dispose(); } }
頁面佈局如下:
void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("簡訊倒計時"),),body: Center( child: ChangeNotifierProvider<TimerModel>( builder: (context) => TimerModel(),child: Consumer<TimerModel>(builder: (context,timerModel,_) { return RaisedButton( onPressed: () async { if (timerModel.count == 0) { timerModel.startTimer(); } },child: Text( timerModel.count == 0 ? "獲取驗證碼" : '${timerModel.count} 秒後重發',style: timerModel.count == 0 ? TextStyle(color: Colors.blue,fontSize: 14) : TextStyle(color: Colors.grey,fontSize: 14),); }),) ); } }
可以看到MyApp是繼承自 StatelessWidget的,是一個沒有狀態的widget。
通過在TimerModel中呼叫notifyListeners();實現重新整理的效果。
2、StreamBuilder實現區域性重新整理
import 'package:flutter/material.dart'; import 'dart:async'; import 'package:rxdart/rxdart.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final StreamController _streamController = StreamController<int>(); int count = 10; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("簡訊倒計時"),body: Center( child: StreamBuilder<int>( stream: _streamController.stream,initialData: 0,builder: (BuildContext context,AsyncSnapshot<int> snapshot) { return RaisedButton( onPressed: () async { if (snapshot.data == 0) { startTimer(); } },child: Text( snapshot.data == 0 ? "獲取驗證碼" : '${snapshot .data} 秒後重發',style: snapshot.data == 0 ? TextStyle(color: Colors.blue,); } ),) ); } startTimer(){ count = 10; Observable.periodic(Duration(seconds: 1)) .take(10) .listen((t){ _streamController.sink.add(--count); }); } }
使用StreamBuilder來區域性重新整理,通過sink.add方法向streamController.sink中新增一個事件流,這個流會被StreamBuilder中stream接收,然後觸發builder方法。
最後在頁面銷燬的時候釋放資源。
效果圖
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。