Reputation: 396
I have a widget hierarchy where SingleChildScrollView
is the parent with a Stack
as the child, the Stack
has two children, if the Second child goes beyond the screen height its height gets clipped. According to docs the stack occupies size according to a Non-Positioned
child. So that means we have to explicitly give a height to the Stack
, but this height is arbitrary and it won't wrap the contents inside. My main aim is to wrap the SingleChildScrollView
height rather than having empty space at bottom.
SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height + 150,
child: SafeArea(
bottom: false,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(height:MediaQuery.of(context).size.height * .35,),
Positioned(top: top: MediaQuery.of(context).size.height * .35 +
MediaQuery.of(context).viewInsets.top,..)
...]))))
[![image][1]][1]
[1]: https://i.sstatic.net/ZnoP0.png
Upvotes: 11
Views: 9648
Reputation: 396
I had finally achieved it by Translating the bottom section along y axis by -20.0 units, that way it overlapped the top section. Which i think was the only way to achieve this for the particular scenario. For other good solutions in other scenarios check @copsOnRoad's fantastic writeup below
Transform.translate(
offset: Offset(0.0, -20.0),
child: Container(
height: 100.0,
width: 100.0,
color: Colors.yellow,
),
),
Upvotes: 0
Reputation: 267584
Do let me know if this isn't what you were looking for.
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 44, left: 24, right: 24, bottom: 20),
color: Colors.deepPurpleAccent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
color: Colors.white,
),
Spacer(),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
color: Colors.white,
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(color: Colors.white, width: 100, height: 100),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_myText("Your name", 16),
_myText("24 years old", 14),
SizedBox(height: 6),
_myText("Martial status", 16),
_myText("Unmarried", 14),
SizedBox(height: 6),
Container(padding: EdgeInsets.all(4), color: Colors.blue, child: _myText("PLUS PLAN - 1 DAY LEFT", 12)),
SizedBox(height: 12),
],
),
),
],
),
SizedBox(
width: double.maxFinite,
child: OutlineButton(
borderSide: BorderSide(color: Colors.white, width: 2),
onPressed: () {},
child: _myText("CHANGE PLAN", 16),
),
),
Text(
"Higher plans give you more connects",
style: TextStyle(fontSize: 10, color: Colors.white70),
),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
_buildCard1(),
_buildCard(size: 70, color: Colors.deepOrange),
_buildCard(size: 80, color: Colors.purple),
_buildCard(size: 90, color: Colors.pink),
_buildCard(size: 100, color: Colors.grey),
],
),
),
],
),
);
}
Widget _myText(String data, double size) => Text(data, style: TextStyle(fontSize: size, color: Colors.white));
Widget _buildCard1() {
return Card(
elevation: 4,
margin: EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("PROFILE DETAILS"),
),
Placeholder(fallbackHeight: 200),
Divider(),
SizedBox(
width: double.maxFinite,
child: FlatButton(
onPressed: () {},
child: Text("UPDATE MY PROFILE"),
),
),
],
),
);
}
Widget _buildCard({double size, Color color}) {
return Card(
margin: EdgeInsets.all(12),
child: Container(height: size, color: color,),
);
}
}
Is this what you were looking for? (Here I only modified above build()
method, rest of the method remains same.
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepPurpleAccent,
body: SafeArea(
child: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 12, left: 24, right: 24, bottom: 20),
color: Colors.deepPurpleAccent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
color: Colors.white,
),
Spacer(),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
color: Colors.white,
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(color: Colors.white, width: 100, height: 100),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_myText("Your name", 16),
_myText("24 years old", 14),
SizedBox(height: 6),
_myText("Martial status", 16),
_myText("Unmarried", 14),
SizedBox(height: 6),
Container(padding: EdgeInsets.all(4), color: Colors.blue, child: _myText("PLUS PLAN - 1 DAY LEFT", 12)),
SizedBox(height: 12),
],
),
),
],
),
SizedBox(
width: double.maxFinite,
child: OutlineButton(
borderSide: BorderSide(color: Colors.white, width: 2),
onPressed: () {},
child: _myText("CHANGE PLAN", 16),
),
),
Text(
"Higher plans give you more connects",
style: TextStyle(fontSize: 10, color: Colors.white70),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.horizontal(left: Radius.circular(30), right: Radius.circular(30))
),
child: Column(
children: <Widget>[
_buildCard1(),
_buildCard(size: 70, color: Colors.deepOrange),
_buildCard(size: 80, color: Colors.purple),
_buildCard(size: 90, color: Colors.pink),
_buildCard(size: 100, color: Colors.grey),
],
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: DecoratedBox(
decoration: BoxDecoration(image: DecorationImage(image: AssetImage("your_image_here"), fit: BoxFit.cover)),
child: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 300,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
background: Container(
decoration: BoxDecoration(image: DecorationImage(image: AssetImage("your_image_here"), fit: BoxFit.cover)),
padding: EdgeInsets.only(top: 12, left: 24, right: 24, bottom: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
color: Colors.white,
),
Spacer(),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
color: Colors.white,
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(color: Colors.white, width: 100, height: 100),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_myText("Your name", 16),
_myText("24 years old", 14),
SizedBox(height: 6),
_myText("Martial status", 16),
_myText("Unmarried", 14),
SizedBox(height: 6),
Container(padding: EdgeInsets.all(4), color: Colors.blue, child: _myText("PLUS PLAN - 1 DAY LEFT", 12)),
SizedBox(height: 12),
],
),
),
],
),
SizedBox(
width: double.maxFinite,
child: OutlineButton(
borderSide: BorderSide(color: Colors.white, width: 2),
onPressed: () {},
child: _myText("CHANGE PLAN", 16),
),
),
Text(
"Higher plans give you more connects",
style: TextStyle(fontSize: 10, color: Colors.white70),
),
],
),
),
),
),
SliverList(
delegate: SliverChildListDelegate(
[
Container(
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.horizontal(
left: Radius.circular(30),
right: Radius.circular(30),
)),
child: Column(
children: <Widget>[
_buildCard1(),
_buildCard(size: 100, color: Colors.deepOrange),
_buildCard(size: 80, color: Colors.purple),
_buildCard(size: 100, color: Colors.pink),
_buildCard(size: 180, color: Colors.grey),
],
),
),
],
),
),
],
),
),
),
);
}
Upvotes: 28