Created
December 2, 2019 17:57
-
-
Save Piinks/bbebd4438fca665a33b5dee3acf76d28 to your computer and use it in GitHub Desktop.
RenderSliverFillRemaining
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 MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: HomePage(), | |
routes: <String, WidgetBuilder>{ | |
'/0': (BuildContext context) => NoSizeChildSetByExtent(), | |
'/1': (BuildContext context) => SizedChildSetByExtent(), | |
'/2': (BuildContext context) => ExtentSetByChildSize(), | |
'/3': (BuildContext context) => NestedScrollViewTest(), | |
}, | |
); | |
} | |
} | |
class HomePage extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('SliverFillRemaining Study')), | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: <Widget>[ | |
RaisedButton( | |
child: Text( | |
'Child without size is set by Extent', | |
style: TextStyle(fontSize: 20), | |
), | |
onPressed: () => Navigator.pushNamed(context, '/0'), | |
), | |
RaisedButton( | |
child: Text( | |
'Child with size is overridden by Extent', | |
style: TextStyle(fontSize: 20), | |
), | |
onPressed: () => Navigator.pushNamed(context, '/1'), | |
), | |
RaisedButton( | |
child: Text( | |
'Extent is overridden by Child size', | |
style: TextStyle(fontSize: 20), | |
), | |
onPressed: () => Navigator.pushNamed(context, '/2'), | |
), | |
RaisedButton( | |
child: Text( | |
'Nested Scroll View Tests', | |
style: TextStyle(fontSize: 20), | |
), | |
onPressed: () => Navigator.pushNamed(context, '/3'), | |
), | |
], | |
), | |
); | |
} | |
} | |
class NoSizeChildSetByExtent extends StatefulWidget { | |
@override | |
_NoSizeChildSetByExtentState createState() => _NoSizeChildSetByExtentState(); | |
} | |
class _NoSizeChildSetByExtentState extends State<NoSizeChildSetByExtent> { | |
bool fillOverscroll = false; | |
bool hasScrollBody = true; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Child without size is set by Extent')), | |
body: CustomScrollView( | |
slivers: <Widget>[ | |
SliverToBoxAdapter( | |
child: new Container( | |
color: Colors.red[300], | |
height: 150.0, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: fillOverscroll, | |
onChanged: (bool newValue) { | |
setState(() { | |
fillOverscroll = newValue; | |
}); | |
}, | |
), | |
Text( | |
'fillOverscroll', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: hasScrollBody, | |
onChanged: (bool newValue) { | |
setState(() { | |
hasScrollBody = newValue; | |
}); | |
}, | |
), | |
Text( | |
'hasScrollBody', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
], | |
)), | |
), | |
SliverFillRemaining( | |
// Independently, this child does not have a size. It should be set by the extent | |
// to fill the remaining space when hasScrollBody is false. | |
// fillOVerscroll specifies if it should stretch to fill or maintain its size and bounce | |
hasScrollBody: this.hasScrollBody, | |
fillOverscroll: this.fillOverscroll, | |
child: new Container(color: Colors.blue[300]), | |
) | |
], | |
), | |
); | |
} | |
} | |
class SizedChildSetByExtent extends StatefulWidget { | |
@override | |
_SizedChildSetByExtentState createState() => _SizedChildSetByExtentState(); | |
} | |
class _SizedChildSetByExtentState extends State<SizedChildSetByExtent> { | |
bool fillOverscroll = false; | |
bool hasScrollBody = true; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Child with size is overriden by Extent')), | |
body: CustomScrollView( | |
slivers: <Widget>[ | |
SliverFixedExtentList( | |
itemExtent: 150.0, | |
delegate: SliverChildBuilderDelegate( | |
(BuildContext context, int index) { | |
return Container( | |
color: index % 2 == 0 ? Colors.red[300] : Colors.green[300], | |
child: index % 2 == 0 | |
? Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: fillOverscroll, | |
onChanged: (bool newValue) { | |
setState(() { | |
fillOverscroll = newValue; | |
}); | |
}, | |
), | |
Text( | |
'fillOverscroll', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: hasScrollBody, | |
onChanged: (bool newValue) { | |
setState(() { | |
hasScrollBody = newValue; | |
}); | |
}, | |
), | |
Text( | |
'hasScrollBody', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
], | |
) | |
: null, | |
); | |
}, | |
childCount: 1, | |
), | |
), | |
SliverFillRemaining( | |
// Independently, this child has a size of 48. It should be overridden by the | |
// extent to size to fill the remaining space, and adhere to the alignment specified | |
hasScrollBody: hasScrollBody, | |
fillOverscroll: fillOverscroll, | |
// child: Container( | |
child: Column(mainAxisSize: MainAxisSize.min, | |
// color: Colors.blue[300], | |
// child: Align( | |
children: [ | |
Flexible( | |
child: Center(child: FlutterLogo(size: 100)), | |
fit: FlexFit.loose, | |
), | |
RaisedButton( | |
child: Text('Bottom'), | |
onPressed: () {}, | |
), | |
]), | |
) | |
], | |
), | |
); | |
} | |
} | |
class ExtentSetByChildSize extends StatefulWidget { | |
@override | |
_ExtentSetByChildSizeState createState() => _ExtentSetByChildSizeState(); | |
} | |
class _ExtentSetByChildSizeState extends State<ExtentSetByChildSize> { | |
bool fillOverscroll = false; | |
bool hasScrollBody = true; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Extent is overridden by Child size')), | |
body: CustomScrollView( | |
slivers: <Widget>[ | |
SliverToBoxAdapter( | |
child: new Container( | |
color: Colors.red[300], | |
height: 150.0, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: fillOverscroll, | |
onChanged: (bool newValue) { | |
setState(() { | |
fillOverscroll = newValue; | |
}); | |
}, | |
), | |
Text( | |
'fillOverscroll', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Checkbox( | |
value: hasScrollBody, | |
onChanged: (bool newValue) { | |
setState(() { | |
hasScrollBody = newValue; | |
}); | |
}, | |
), | |
Text( | |
'hasScrollBody', | |
style: TextStyle(fontSize: 15), | |
), | |
], | |
), | |
], | |
)), | |
), | |
SliverFixedExtentList( | |
itemExtent: 150.0, | |
delegate: SliverChildBuilderDelegate( | |
(BuildContext context, int index) { | |
return Container( | |
color: | |
index % 2 == 0 ? Colors.yellow[400] : Colors.green[400], | |
); | |
}, | |
childCount: 5, | |
), | |
), | |
SliverFillRemaining( | |
// Independently, this child has a size of 150. Extent should be overridden with | |
// this size since we have scrolled beyond the viewport size. | |
hasScrollBody: hasScrollBody, | |
fillOverscroll: fillOverscroll, | |
child: Container( | |
color: Colors.blue[300], | |
child: Align( | |
alignment: Alignment.center, | |
child: Padding( | |
padding: const EdgeInsets.all(50.0), | |
child: RaisedButton( | |
child: Text('I should hangout in the center. :)'), | |
onPressed: () {}, | |
), | |
), | |
), | |
), | |
) | |
], | |
), | |
); | |
} | |
} | |
class NestedScrollViewTest extends StatelessWidget { | |
// Nested scroll views are built with SliverFillRemaining. | |
// These should be unaffected from the previous expected behavior. | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: DefaultTabController( | |
length: 4, | |
child: NestedScrollView( | |
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { | |
return <Widget>[ | |
SliverAppBar( | |
title: Text('Nested Scroll View Tests'), | |
pinned: true, | |
expandedHeight: 200.0, | |
forceElevated: innerBoxIsScrolled, | |
bottom: const TabBar( | |
tabs: <Tab>[ | |
Tab(text: 'AA'), | |
Tab(text: 'BB'), | |
Tab(text: 'CC'), | |
Tab(text: 'DD'), | |
], | |
), | |
), | |
]; | |
}, | |
body: TabBarView( | |
children: <Widget>[ | |
ListView( | |
children: <Widget>[ | |
Container( | |
height: 300.0, | |
child: const Text('aaa1'), | |
), | |
Container( | |
height: 200.0, | |
child: const Text('aaa2'), | |
), | |
Container( | |
height: 100.0, | |
child: const Text('aaa3'), | |
), | |
Container( | |
height: 50.0, | |
child: const Text('aaa4'), | |
), | |
], | |
), | |
ListView( | |
children: <Widget>[ | |
Container( | |
height: 100.0, | |
child: const Text('bbb1'), | |
), | |
], | |
), | |
Container( | |
child: const Center(child: Text('ccc1')), | |
), | |
ListView( | |
children: <Widget>[ | |
Container( | |
height: 10000.0, | |
child: const Text('ddd1'), | |
), | |
], | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment