Cannot constrain Card's height with SizedBox - flutter

When used inside ListView, Card's width can be controlled with a SizedBox, but height stays unbounded. I would like to know how to limit it.
Widget buildCard(String text) {
return SizedBox(
height: 220.0, // this does not work
width: 180.0, // this works
child: Card(
child: Column(
children: [
ListTile(
title: Text('Title: $text'),
subtitle: Text('Subtitle: $text'),
),
],
),
),
);
}
Widget build(BuildContext context) {
return MaterialApp(
// ...
home: Scaffold(
// ...
body: ListView(
children: [
buildCard('one'),
buildCard('two'),
buildCard('three'),
buildCard('four'),
buildCard('five'),
],
scrollDirection: Axis.horizontal,
),
),
);
}
A demo is available at DartPad.

Give height to ListView only
SizedBox(
height: 220,
child: ListView(
//....

Related

How To Make The Column Scrollable In Flutter Web?

The Parent Widget Is Column,
Column Contains the following children:
STACK
CONTAINER(CHILD: ROW)
ROW(CHILDREN: [GESTUREDETECTOR(child:Container), GESTUREDETECTOR(child:Container)]
LISTVIEW BUILDER
Wrapping this column with expanded, and then with singlechildScrollView. The result is the error!!
WHAT TO DO??
Wrap Column with SinglechildScrollView, for ListView.builder you need to set:
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
In your case widget tree will look like this (minimal reproducible sample)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SingleChildScrollView',
home: Scaffold(
appBar: AppBar(
title: Text('SingleChildScrollView Example'),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: [
Container(
width: 50,
height: 50,
color: Colors.cyan,
),
],
),
Container(
child: Row(
children: [
GestureDetector(
child: Container(
width: 50,
height: 50,
color: Colors.green,
),
),
GestureDetector(
child: Container(
width: 50,
height: 50,
color: Colors.blue,
),
),
],
),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: 60,
itemBuilder: (context, index) => Text('Item # $index'),
)
],
),
)),
);
}
}
And it scrolls.

How to scroll stacked containers with sticky header in Flutter?

I am trying to achieve scroll in Flutter Web where I have few containers which are stacked and I use SingleChildScrollView to scroll the widget. However, when I scroll the first container everything working fine but the second one which is a child of the second container responds to the scroll without completing the initial one. And also is there a way to make a sticky header for the second container. How can I make the 3rd container(orange) to scroll after the 2nd(blue) one is finished scrolling? Here is what I am trying to achieve:
https://yobithemes.com/demo/html/freda/dark-video-index.html
And here what I got so far:
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
IntroScreen(),
SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height - 100,
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.blue,
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height,
),
Container(
padding: EdgeInsets.only(top: 100),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.orange,
),
],
),
),
),
],
),
),
),
],
),
);
}
}
You can achieve it by using sliver.
SliverToBoxAdapter fill the transparent area with screen height - app bar height.
SliverAppBar: make it sticky by setting floating and pin to true
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
IntroScreen(),
CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: MediaQuery.of(context).size.height - 50,
),
),
SliverAppBar(
// toolbarHeight: 50,
floating: true,
pinned: true,
title: Container(
child: Center(child: Text('Header')),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
height: MediaQuery.of(context).size.height-50,
color: Colors.primaries[index % Colors.primaries.length],
),
),
),
],
),
],
),
);
}
}

Make widget Expanded size as min height in SingleChildScrollView Widget

Here is my code
child: Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(),
drawer: MyDrawer(),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
// direction: Axis.vertical,
children: [
Container(
height: 400,
child: Text('PageOne'),
),
IntrinsicHeight(
child: Expanded(
child: Container(
width: double.infinity,
color: Colors.grey,
child: Text(
'Hi',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
),
I want this grey container in the screenshot fill the height as min height, I need it responsively with rotate the screen phone and for all phone screen size, it's only takes static height size when use SingleChildScrollView because unlimited height is available, i try to find way to make him take the remaining height of the screen as min height of container.
any ideas?
If you do know the height of the top part, you could use a mix of LayoutBuilder and ConstrainedBox like so:
import 'dart:math';
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
final double headerHeight = 400;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
// direction: Axis.vertical,
children: [
Container(
color: Colors.red,
height: headerHeight,
child: Text('PageOne'),
),
ConstrainedBox(
constraints: new BoxConstraints(
minHeight: max(0, constraints.maxHeight - headerHeight),
),
child: Container(
width: double.infinity,
color: Colors.grey,
child: Text(
'Hi',
textAlign: TextAlign.center,
),
),
),
],
),
);
}
),
);
}
}
If you don't know the height of the top part, I would use key (or keys) to get their size and use the same widget tree as above.

Column's MainAxisSize.min and ListView's shrinkWrap: true are not working when inside a container with full height

If you create a container that takes the full height of the screen and place either a Column with its mainAxisSize property as MainAxisSize.min or a ListView with its shrinkWrap property as true these values are ignored and the Column/ListView will take up the full height of the container.
Here are code examples to illustrate this:
///Column
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
Text('1'),
Text('2'),
Text('3'),
],
),
),
);
}
OR
///ListView
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
child: ListView(
shrinkWrap: true,
children: const [
Text('1'),
Text('2'),
Text('3'),
],
),
),
);
}
How can I have a column or ListView only take up the size of its content when it's placed inside a container that has the full height of the window?
you can wrap it inside a Column and include
Expanded/Flexible for other widgets like below example:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
color: Colors.pink,
child: Column(children: [
Column(
mainAxisSize: MainAxisSize.max,
children: const [
Text('1'),
Text('2'),
Text('3'),
],
),
Expanded(child: Container(color: Colors.green))
]),
),
);
}

ShrinkWrap Horizontal ListView inside Column with 'mainAxisSize: MainAxisSize.min' gives error : 'constraints.hasBoundedHeight': is not true

I am trying to display a horizontal ListView which height is given by its children inside a Column which height is also this of its children.
However, I'm getting the following error : 'constraints.hasBoundedHeight': is not true.
Here is a simple snippet to reproduce the error:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
main() => runApp(MaterialApp(
home: Scaffold(
body: MyApp(),
),
));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Vertical1'),
ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: <Widget>[
Container(
height: 100,
width: 100,
child: Text('Horizontal1'),
color: Colors.red,
),
],
),
Text('Vertical2')
],
);
}
}
As you see the children have a defined height so I don't get the issue.
Here is the expected output:
I know I can use a SingleChildScrollView but would just like to understand why it does not work with a ListView.
Just because your child has a size does not mean the ListView will take on that size.
You need to give a height to your ListView because by default its height is infinite.
You get this error because you can't place infinite height in a column,
so you give it a height with the widget Expanded if you want your list to take all the space available.
Here is an example:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Container(color: Colors.red, child: Text('Vertical1')),
ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 100,
),
child: Container(
color: Colors.green,
child: ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: <Widget>[
Container(
height: 100,
width: 100,
child: Text('Horizontal1'),
),
],
),
),
),
Container(color: Colors.red, child: Text('Vertical2'))
],
),
),
);
}
}