Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Flutter Simple inherited Widget Example
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);
}
},
),
);
}
}
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),
),
);
}
}
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;
}
@lukepighetti

This comment has been minimized.

Copy link

@lukepighetti lukepighetti commented Jul 19, 2018

Got anything simpler?

@Grumpf86

This comment has been minimized.

Copy link

@Grumpf86 Grumpf86 commented Jul 20, 2018

Thank you for this example. :-)
Keeping a state in flutter is not that easy ... :P
I'm lucky the state of my hard drive is not that "volatile"

@function1983

This comment has been minimized.

Copy link

@function1983 function1983 commented Aug 10, 2018

Thank you. Very good example and I feel very comfortable with just enough complexity. But for starters or absolute beginners, a diagram that map out the design for this particular app would be very helpful.

@xuesongcc

This comment has been minimized.

Copy link

@xuesongcc xuesongcc commented Aug 14, 2018

Thank you for this example.:)
i have a problem:
https://gist.github.com/ericwindmill/f790bd2456e6489b1ab97eba246fd4c6#file-form_page-dart-L75
How does this function become optional?

@lifenautjoe

This comment has been minimized.

Copy link

@lifenautjoe lifenautjoe commented Oct 5, 2018

Please rename to "Flutter Complex inherited Widget Example"

@cgustav

This comment has been minimized.

Copy link

@cgustav cgustav commented Nov 10, 2019

Cool! it works for me! thanks

@opalr

This comment has been minimized.

Copy link

@opalr opalr commented Mar 5, 2020

I found an issue. If you're on the 2nd page of a PageView and you press a button that runs container.updateUserInfo(), the PageView returns to its first page. I'm guessing this is because the PageView rebuilds and loses its state. How would you prevent PageView from returning to its first page in this case?

@dishangPatel

This comment has been minimized.

Copy link

@dishangPatel dishangPatel commented Apr 26, 2020

Anyone have an idea why, this code directly returned true from updateShouldNotify method, without comparing data object?

@sagreine

This comment has been minimized.

Copy link

@sagreine sagreine commented Jun 28, 2020

Nowadays you might use:

return (context.dependOnInheritedWidgetOfExactType<_InheritedStateContainer>()
            ).data;

instead of:

return (context.inheritFromWidgetOfExactType(_InheritedStateContainer)
            as _InheritedStateContainer)
        .data;

given inheritFromWidgetOfExactType is deprecated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.