把這幾天了解學(xué)習(xí)的知識(shí)匯總了一下,掌握flutter以下幾種方式即可應(yīng)對(duì)各種場(chǎng)景了厂镇。
一纤壁、監(jiān)聽回調(diào)
場(chǎng)景,A頁(yè)面實(shí)現(xiàn)回調(diào)方法并綁定自定義抽象類捺信,在B頁(yè)面觸發(fā)回調(diào)A頁(yè)面的回調(diào)方法酌媒。
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
void main() {
? runApp(new RootLayout());
}
class RootLayout extends StatefulWidget {
? @override
? State<StatefulWidget> createState() {
? ? return new RootLayoutM();
? }
}
class RootLayoutM extends State<RootLayout> implements OnDialogClickListener {
? String str = "show simple dialog";
? String showMsg = "show simple dialog";
? @override
? void onOk() {
? ? print('onOK');
? ? setState(() {
? ? ? showMsg = str + " onOK Click";
? ? });
? }
? @override
? void onCancel() {
? ? print('onCancel');
? ? setState(() {
? ? ? showMsg = str + " onCancel Click";
? ? });
? }
? @override
? Widget build(BuildContext context) {
? ? return new MaterialApp(
? ? ? ? home: new Scaffold(
? ? ? body: new Center(
? ? ? ? child:
? ? ? ? ? ? new Text(showMsg, style: new TextStyle(color: Color(0xFF00FF00))),
? ? ? ),
? ? ? floatingActionButton: new MyFloat(this),
? ? ));
? }
}
//定義一個(gè)抽象類
abstract class OnDialogClickListener {
? void onOk();
? void onCancel();
}
class MyFloat extends StatelessWidget {
? final OnDialogClickListener callback;
? MyFloat(this.callback);
? _showMyMaterialDialog(BuildContext context) {
? ? print("_showMyMaterialDialog");
? ? showDialog(
? ? ? ? context: context,
? ? ? ? builder: (context) {
? ? ? ? ? return new AlertDialog(
? ? ? ? ? ? title: new Text("title"),
? ? ? ? ? ? content: new Text("內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容"),
? ? ? ? ? ? actions: <Widget>[
? ? ? ? ? ? ? new FlatButton(
? ? ? ? ? ? ? ? onPressed: () {
? ? ? ? ? ? ? ? ? callback.onOk();
? ? ? ? ? ? ? ? ? Navigator.of(context).pop();
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? child: new Text("確認(rèn)"),
? ? ? ? ? ? ? ),
? ? ? ? ? ? ? new FlatButton(
? ? ? ? ? ? ? ? onPressed: () {
? ? ? ? ? ? ? ? ? callback.onCancel();
? ? ? ? ? ? ? ? ? Navigator.of(context).pop();
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? child: new Text("取消"),
? ? ? ? ? ? ? ),
? ? ? ? ? ? ],
? ? ? ? ? );
? ? ? ? });
? }
? @override
? Widget build(BuildContext context) {
? ? // TODO: implement build
? ? return new FloatingActionButton(
? ? ? ? child: new Text("showDialog"),
? ? ? ? onPressed: () {
? ? ? ? ? _showMyMaterialDialog(context);
? ? ? ? });
? }
}
二、父頁(yè)面調(diào)用子頁(yè)面
這里使用全局key>GlobalKey來調(diào)用子頁(yè)的方法或者公共屬性.全局key比較耗能。謹(jǐn)慎使用馍佑。GlobalKey每個(gè)globalkey都是一個(gè)在整個(gè)應(yīng)用內(nèi)唯一的key斋否。globalkey相對(duì)而言是比較昂貴的,如果你并不需要globalkey的某些特性拭荤,那么可以考慮使用Key茵臭、ValueKey、ObjectKey或UniqueKey舅世。
注意:該場(chǎng)景是全局key旦委,意思可以在任意地方使用。
用法:1.在即將被調(diào)用的頁(yè)面聲明接收構(gòu)造方法,接收參數(shù)Globalkey。
????????????2.在使用的頁(yè)面芋簿,new一個(gè)有即將被調(diào)用頁(yè)面狀態(tài)的Globalkey,在生成被調(diào)用頁(yè)面時(shí)傳入這個(gè)globalkey,即可在使用頁(yè)面隨意調(diào)用被調(diào)用頁(yè)的公共屬性查辩、方法!
其它key擴(kuò)展网持,參考
ValueKey:以一個(gè)值為key宜岛。
????????ObjectKey:以一個(gè)對(duì)象為key。
????????UniqueKey:生成唯一的隨機(jī)數(shù)作為key功舀。
????????PageStorageKey:專用于存儲(chǔ)頁(yè)面滾動(dòng)位置的key萍倡。
父頁(yè)面.
class ParentScreen extends StatefulWidget {
? ? @override
? ? _ParentScreenState createState() => _ParentScreenState();
}
class _ParentScreenState extends State<ParentScreen> {
GlobalKey<_ChildScreenState> childKey = GlobalKey();
? ? @override
? ? Widget build(BuildContext context) {
? ? ? ? return Column(
? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? ? ChildScreen(
? ? ? ? ? ? ? ? ? ? key: childKey
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? RaisedButton(
? ? ? ? ? ? ? ? ? ? onPressed: (){
? ? ? ? ? ? ? ? ? ? ? ? childKey.currentState.childFunction();
? ? ? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? ? ? child: Text('點(diǎn)擊我調(diào)用子組件方法'),
? ? ? ? ? ? ? ? )
? ? ? ? ? ? ],
? ? ? ? );
? ? }
}
子頁(yè)面.
class ChildScreen extends StatefulWidget {
? ? ChildScreen({
? ? ? ? Key key,
? ? }) : super(key: key);
? ? @override
? ? _ChildScreenState createState() => _ChildScreenState();
}
class _ChildScreenState extends State<ChildScreen> {
? ? @override
? ? Widget build(BuildContext context) {
? ? ? ? return Container(
? ? ? ? );
? ? }
? ? childFunction(){
? ? ? ? print('this is a childFunction');
? ? }
}
三、數(shù)據(jù)監(jiān)聽
ValueListenableBuilder,監(jiān)聽數(shù)據(jù)變化(單個(gè)數(shù)值或者對(duì)象)辟汰,比較適合組件的局部刷新列敲。
使用場(chǎng)景,A頁(yè)面點(diǎn)擊item后刷新復(fù)選框帖汞,復(fù)選按鈕等戴而。還有收藏一件商品刷新購(gòu)物車的右上角的件數(shù)。
也有人弄成多個(gè)地方的刷新翩蘸,但個(gè)人覺得不適合填硕,如果多地方還是考慮使用setstate,不能本末倒置鹿鳖,還是應(yīng)該恰到好處。
class MyHomePage extends StatefulWidget {
? MyHomePage({Key key, this.title}) : super(key: key);
? final String title;
? @override
? _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
? final ValueNotifier<int> _counter = ValueNotifier<int>(0);
? final Widget goodJob = const Text('Good job!');
? @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:'),
? ? ? ? ? ? ValueListenableBuilder(
? ? ? ? ? ? ? builder: (BuildContext context, int value, Widget child) {
? ? ? ? ? ? ? ? // This builder will only get called when the _counter
? ? ? ? ? ? ? ? // is updated.
? ? ? ? ? ? ? ? return Row(
? ? ? ? ? ? ? ? ? mainAxisAlignment: MainAxisAlignment.spaceEvenly,
? ? ? ? ? ? ? ? ? children: <Widget>[
? ? ? ? ? ? ? ? ? ? Text('$value'),
? ? ? ? ? ? ? ? ? ? child,
? ? ? ? ? ? ? ? ? ],
? ? ? ? ? ? ? ? );
? ? ? ? ? ? ? },
? ? ? ? ? ? ? valueListenable: _counter,
? ? ? ? ? ? ? // The child parameter is most helpful if the child is
? ? ? ? ? ? ? // expensive to build and does not depend on the value from
? ? ? ? ? ? ? // the notifier.
? ? ? ? ? ? ? child: goodJob,
? ? ? ? ? ? )
? ? ? ? ? ],
? ? ? ? ),
? ? ? ),
? ? ? floatingActionButton: FloatingActionButton(
? ? ? ? child: Icon(Icons.plus_one),
? ? ? ? onPressed: () => _counter.value += 1,
? ? ? ),
? ? );
? }
}
四壮莹、正常傳參
場(chǎng)景翅帜,A頁(yè)面?zhèn)髦到oB頁(yè)面,B頁(yè)面返回?cái)?shù)值命满。例如涝滴,選擇日期,返回選中值
這類比較普通就放最后了
如果單純A傳B,只需要在A頁(yè)面構(gòu)造函數(shù)中聲明參數(shù)歼疮,q
且:
Navigator.push(context, new MaterialPageRoute<void> (
? ? ? ? return A(name:xxx);
));
如果需要B返回值杂抽,既可以
await Navigator.pushNamed(context,'/router/文件名').then((value){print(value);// --> abc});