Created
April 14, 2018 19:25
-
-
Save ericwindmill/f790bd2456e6489b1ab97eba246fd4c6 to your computer and use it in GitHub Desktop.
Flutter Simple inherited Widget Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:simple_inherit/state_container.dart'; | |
class UpdateUserScreen extends StatelessWidget { | |
static final GlobalKey<FormState> formKey = new GlobalKey<FormState>(); | |
static final GlobalKey<FormFieldState<String>> firstNameKey = | |
new GlobalKey<FormFieldState<String>>(); | |
static final GlobalKey<FormFieldState<String>> lastNameKey = | |
new GlobalKey<FormFieldState<String>>(); | |
static final GlobalKey<FormFieldState<String>> emailKey = | |
new GlobalKey<FormFieldState<String>>(); | |
final User user; | |
const UpdateUserScreen({Key key, this.user}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
final container = StateContainer.of(context); | |
return new Scaffold( | |
appBar: new AppBar( | |
title: new Text('Edit User Info'), | |
), | |
body: new Padding( | |
padding: new EdgeInsets.all(16.0), | |
child: new Form( | |
key: formKey, | |
autovalidate: false, | |
child: new ListView( | |
children: [ | |
new TextFormField( | |
key: firstNameKey, | |
style: Theme.of(context).textTheme.headline, | |
decoration: new InputDecoration( | |
hintText: 'First Name', | |
), | |
), | |
new TextFormField( | |
key: lastNameKey, | |
style: Theme.of(context).textTheme.headline, | |
decoration: new InputDecoration( | |
hintText: 'Last Name', | |
), | |
), | |
new TextFormField( | |
key: emailKey, | |
style: Theme.of(context).textTheme.headline, | |
decoration: new InputDecoration( | |
hintText: 'Email Address', | |
), | |
) | |
], | |
), | |
), | |
), | |
floatingActionButton: new FloatingActionButton( | |
child: new Icon(Icons.add), | |
onPressed: () { | |
final form = formKey.currentState; | |
if (form.validate()) { | |
var firstName = firstNameKey.currentState.value; | |
var lastName = lastNameKey.currentState.value; | |
var email = emailKey.currentState.value; | |
if (firstName == '') { | |
firstName = null; | |
} | |
if (lastName == '') { | |
lastName = null; | |
} | |
if (email == '') { | |
email = null; | |
} | |
container.updateUserInfo( | |
firstName: firstName, | |
lastName: lastName, | |
email: email, | |
); | |
Navigator.pop(context); | |
} | |
}, | |
), | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:simple_inherit/form_page.dart'; | |
import 'package:simple_inherit/state_container.dart'; | |
void main() { | |
runApp(new StateContainer(child: new TodoApp())); | |
} | |
class TodoApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
title: 'Some Todos', | |
home: new HomeScreen(), | |
); | |
} | |
} | |
class HomeScreen extends StatefulWidget { | |
@override | |
HomeScreenState createState() => new HomeScreenState(); | |
} | |
class HomeScreenState extends State<HomeScreen> { | |
User user; | |
Widget get _userInfo { | |
return new Center( | |
child: new Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: <Widget>[ | |
new Text("${user.firstName} ${user.lastName}", | |
style: new TextStyle(fontSize: 24.0)), | |
new Text(user.email, style: new TextStyle(fontSize: 24.0)), | |
], | |
), | |
); | |
} | |
Widget get _logInPrompt { | |
return new Center( | |
child: new Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
children: <Widget>[ | |
new Text('Please add user information'), | |
], | |
), | |
); | |
} | |
void _updateUser(BuildContext context) { | |
Navigator.push( | |
context, | |
new MaterialPageRoute( | |
fullscreenDialog: true, | |
builder: (context) { | |
return new UpdateUserScreen(); | |
}, | |
), | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
final container = StateContainer.of(context); | |
user = container.user; | |
var body = user != null ? _userInfo : _logInPrompt; | |
return new Scaffold( | |
appBar: new AppBar( | |
title: new Text('Inherited Widget Test'), | |
), | |
body: body, | |
floatingActionButton: new FloatingActionButton( | |
onPressed: () => _updateUser(context), | |
child: new Icon(Icons.edit), | |
), | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/foundation.dart'; | |
class User { | |
String firstName; | |
String lastName; | |
String email; | |
User(this.firstName, this.lastName, this.email); | |
} | |
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 | |
StateContainerState createState() => new StateContainerState(); | |
} | |
class StateContainerState extends State<StateContainer> { | |
User user; | |
void updateUserInfo({firstName, lastName, email}) { | |
if (user == null) { | |
user = new User(firstName, lastName, email); | |
setState(() { | |
user = user; | |
}); | |
} else { | |
setState(() { | |
user.firstName = firstName ?? user.firstName; | |
user.lastName = lastName ?? user.lastName; | |
user.email = email ?? user.email; | |
}); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return new _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(_InheritedStateContainer old) => true; | |
} |
Nowadays you might use:
return (context.dependOnInheritedWidgetOfExactType<_InheritedStateContainer>()
).data;
instead of:
return (context.inheritFromWidgetOfExactType(_InheritedStateContainer)
as _InheritedStateContainer)
.data;
given inheritFromWidgetOfExactType is deprecated
"StateContainerState"
This example is very cool. I understood the logic behind state management mechanisms.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Anyone have an idea why, this code directly returned true from updateShouldNotify method, without comparing data object?