Last active
May 15, 2020 20:31
-
-
Save devkabiir/9e35ba5c2dd938a267f0a1a0daf814a7 to your computer and use it in GitHub Desktop.
Inherit property or parameters from parent widget
This file contains 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'; | |
void main() => runApp(MyApp()); | |
class BaseScreen1 extends StatelessWidget { | |
final LayoutWidgetBuilder builder; | |
const BaseScreen1({this.builder}); | |
@override | |
Widget build(BuildContext context) { | |
var safePadding = MediaQuery.of(context).padding.top + | |
MediaQuery.of(context).padding.bottom; | |
return Scaffold( | |
body: LayoutBuilder( | |
builder: (context, constraint) { | |
return SingleChildScrollView( | |
child: SafeArea( | |
child: ConstrainedBox( | |
constraints: BoxConstraints( | |
minHeight: constraint.maxHeight - safePadding, | |
), | |
child: builder(context, constraint), | |
), | |
), | |
); | |
}, | |
), | |
); | |
} | |
} | |
class BaseScreen2 extends StatelessWidget { | |
final Widget child; | |
const BaseScreen2({this.child}); | |
@override | |
Widget build(BuildContext context) { | |
var safePadding = MediaQuery.of(context).padding.top + | |
MediaQuery.of(context).padding.bottom; | |
return Scaffold( | |
body: LayoutBuilder( | |
builder: (context, constraint) { | |
return SingleChildScrollView( | |
child: SafeArea( | |
child: ConstrainedBox( | |
constraints: BoxConstraints( | |
minHeight: constraint.maxHeight - safePadding, | |
), | |
child: | |
InheritedConstraint(constraint: constraint, child: child), | |
), | |
), | |
); | |
}, | |
), | |
); | |
} | |
} | |
/// [InheritedWidget]s are very efficient, in fact they are used throughout | |
/// flutter's source code. Even the `MediaQuery.of(context)` and `Theme.of(context)` | |
/// is actually an [InheritedWidget] | |
class InheritedConstraint extends InheritedWidget { | |
const InheritedConstraint({ | |
Key key, | |
@required this.constraint, | |
@required Widget child, | |
}) : assert(constraint != null), | |
assert(child != null), | |
super(key: key, child: child); | |
final BoxConstraints constraint; | |
static InheritedConstraint of(BuildContext context) { | |
return context.dependOnInheritedWidgetOfExactType<InheritedConstraint>(); | |
} | |
@override | |
bool updateShouldNotify(covariant InheritedConstraint old) => | |
constraint != old.constraint; | |
} | |
extension $InheritedConstraint on BuildContext { | |
/// Get the constraints provided by parent widget | |
BoxConstraints get constraints => InheritedConstraint.of(this).constraint; | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
debugShowCheckedModeBanner: false, | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyHomePage(), | |
); | |
} | |
} | |
class ChildUsingInheritedWidget extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
/// Get the constrains provided by parent widget | |
final constraint = context.constraints; | |
// TODO: use the constraints as you wish | |
return Container( | |
color: Colors.green, | |
height: constraint.minHeight, | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key}) : super(key: key); | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
bool useInheritedWidget = true; | |
void toggle(bool state) { | |
setState(() { | |
useInheritedWidget = state; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
Text('Current pattern: ' + | |
(useInheritedWidget ? 'InheritedWidget' : 'LayoutWidgetBuilder')), | |
Switch.adaptive(value: useInheritedWidget, onChanged: toggle), | |
if (useInheritedWidget) | |
/// The child will automatically use the [constraint] from parent | |
Expanded(child: BaseScreen2(child: ChildUsingInheritedWidget())) | |
else | |
/// This is just like using [LayoutBuilder] but only one | |
/// LayoutBuilder is used and the constraints are passed down to child | |
Expanded( | |
child: BaseScreen1( | |
builder: (context, constraint) { | |
// TODO: use the constraints as you wish | |
return Container( | |
color: Colors.blue, | |
height: constraint.minHeight, | |
); | |
}, | |
), | |
), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment