
在多层级的 StatefulWidget 进行传递数据是比较麻烦的事情,不过今天详情的
无论是前台还是 Android 开发,在组件化的今天我们都需要给出一个套数据在组件间传递的方案。
不过公告一下今天分享的数据传递方式并不是最理想数据传递方式随后还会详情其余。不过随着业务不多复杂我们传递数据
图
屏幕快照 2019-06-26 上午5.47.19.pngimport 'package:flutter/material.dart';import 'pages/home_screen.dart';void main() { runApp( new HomeApp(), );}class HomeApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp(title: 'Demo', home: new HomeScreen()); }}上面的代码在普通不过,而后创立 HomeApp 页面来启动 HomeScreen 页面。下面是 HomeScreen 的主页面。HomeScreen 是一个 StatefulWidget 组件。
import 'package:flutter/material.dart';class HomeScreen extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return _HomeScreenState(); }}class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("Flutter Inherited Widget Demo"), ), body: Container( alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ ], ), ), ); }}随着详情 InheritedWidget 同时也给大家解释少量常用组件 Container 是容器组件,假如想让组件按列排列即可以用 Colum。mainAxisAlignment 表示按横向而 crossAxisAlignment 表示纵向上组件对齐的方式,他们会根据 Row 和 Colum 排列方式不同而不同?。?
children: <Widget>[ Text("Name: "), SizedBox( height: 20.0, ), RaisedButton( child: Text("Add Name"), onPressed: (){ }, ) ],
图 openForm(BuildContext context) { //Open form }点击按钮后调用 openForm 来打开一个表单页。继续创立一个 FormScreen 页面,这个页面相对复杂,需要花时间说明一下?。?
import 'package:flutter/material.dart';class FormScreen extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return _FormScreenState(); }}class _FormScreenState extends State<FormScreen> { String name; final formKey = new GlobalKey<FormState>(); validateAndSave() { if (formKey.currentState.validate()) { formKey.currentState.save(); Navigator.pop(context); } else { print("validation Enter"); } } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("Flutter Inherited Widget Demo"), ), body: Container( alignment: Alignment.center, child: Form( key: formKey, child: Padding( padding: EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ TextFormField( keyboardType: TextInputType.text, decoration: InputDecoration(labelText: "name"), validator: (val) => val.length == 0 ? "Enter Name" : null, onSaved: (val) => name = val, ), RaisedButton( child: Text("save"), onPressed: validateAndSave, ) ], ), ), )), ); }}创立一个表单给 FormKey,给 key 是便于 element 可以通过 key 找到表单而不是仅仅根据类型来找到 element 对应 widge,这个随后给大家详情。
TextFormField 作为一个相对复杂常用表单组件通过 keyboardType 定义他的类型,validator 可以写其校验函数,也就是我们定义校验的规则,noSave 也就是当提交表单时候的函数?。
formKey.currentState.validate() 来判断能否校验通过,校验通过后会返回到 Screen 页面?
class User { String name; User({this.name});}我们定义一个 User 类,作为数据模型。
import 'package:flutter/material.dart';import '../model/user.dart';class StateContainer extends StatefulWidget { final Widget child; final User user; StateContainer(@required this.child, this.user); static _StateContainerState of(BuildContext context) { return (context.inheritFromWidgetOfExactType(InheritedStateContainer) as InheritedStateContainer) .data; } @override State<StatefulWidget> createState() { // TODO: implement createState return _StateContainerState(); }}class _StateContainerState extends State<StateContainer> { User user; void updateUser({name}) { if (user == null) { user = User(name: name); setState(() { user = user; }); } else { setState(() { user.name = name ?? user.name; }); } } @override Widget build(BuildContext context) { // TODO: implement build return InheritedStateContainer( data: this, child: widget.child, ); }}class InheritedStateContainer extends InheritedWidget { final _StateContainerState data; InheritedStateContainer({ Key key, @required this.data, @required Widget child, }) : super(key: key, child: child); @override bool updateShouldNotify(InheritedWidget oldWidget) { // TODO: implement updateShouldNotify return true; }}import 'package:flutter/material.dart';import 'pages/home_screen.dart';import 'pages/state_container.dart';void main() { runApp(StateContainer(HomeApp(), null));}class HomeApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp(title: 'Demo', home: HomeScreen()); }}import 'package:flutter/material.dart';import '../model/user.dart';import 'state_container.dart';class FormScreen extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return _FormScreenState(); }}class _FormScreenState extends State<FormScreen> { String name; final formKey = new GlobalKey<FormState>(); validateAndSave() { final container = StateContainer.of(context); if (formKey.currentState.validate()) { formKey.currentState.save(); container.updateUser(name: name); Navigator.pop(context); } else { print("validation Enter"); } } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("Flutter Inherited Widget Demo"), ), body: Container( alignment: Alignment.center, child: Form( key: formKey, child: Padding( padding: EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ TextFormField( keyboardType: TextInputType.text, decoration: InputDecoration(labelText: "name"), validator: (val) => val.length == 0 ? "Enter Name" : null, onSaved: (val) => name = val, ), RaisedButton( child: Text("save"), onPressed: validateAndSave, ) ], ), ), )), ); }}import 'package:flutter/material.dart';import 'my_form.dart';import '../model/user.dart';import 'state_container.dart';class HomeScreen extends StatefulWidget { @override State<StatefulWidget> createState() { // TODO: implement createState return _HomeScreenState(); }}class _HomeScreenState extends State<HomeScreen> { User user; openForm(BuildContext context) { //Open form Navigator.push( context, MaterialPageRoute( fullscreenDialog: true, builder: (context) { return FormScreen(); })); } @override Widget build(BuildContext context) { final container = StateContainer.of(context); user = container.user; // TODO: implement build return Scaffold( appBar: AppBar( title: Text("Flutter Inherited Widget Demo"), ), body: Container( alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ user != null ? Text("Name: ${user.name}") : Text("No name"), SizedBox( height: 20.0, ), RaisedButton( child: Text("Add Name"), onPressed: () { openForm(context); }, ) ], ), ), ); }}