ExpansionTile and SingleChildScrollView not working together in Flutter? - flutter

How can I avoid the overflowing in my text when using ExpansionTile widget? When I was not using this widget my text was not overflowing and using SingleChildScrollView was enough.
ExpansionTile(
title: Text('History'),
children: [
SingleChildScrollView(
child:Text(widget.descriptionText as String),
),
]
)

A single child scroll view can take infinite height if not bound. You can try wrapping it with a sizedBox of specific height
ExpansionTile(
title: Text('History'),
children: [
SizedBox(
height: 500,
width: MediaQuery.of(context).size width*0.7,
child: SingleChildScrollView(
child:Text(widget.descriptionText as String),
),
)
]
)

Related

Flutter Expanded widget content won't scroll

When my Expanded widget has expanded there are 20 items, which cause a vertical overflow issue. How do I get the contents within Expanded widget to scroll? I've tried wrapping the content in a SinglechildScrollView but it still didn't allow scrolling.
Scaffold(
key: key,
appBar: customappbar,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
ExpansionTile(
title: Text(
"${_getcurrentselection(context)}:",
style: const TextStyle(fontSize: 16),
),
children: <Widget>[
for (Map<String, dynamic> submenuitemdata in subMenuItems)
Padding(
padding: const EdgeInsets.only(bottom:10.0),
child: SubmenuItem(submenuitem: submenuitemdata),
),
Expanded(
child: WebViewWidget(controller: controllerGlobal),
),
],
),
],
),
),
Try putting your widgets inside a ListView which should be inside the Expanded.
I couldn't find a suitable solution sa the Expanded widget below the ExpansionTile widget kept throwing errors no matter what I tried. Instead I placed both inside a Stack, so that the ExpansionTile expands over the top of any other widgets.
Also, minus 2 was a bit harsh

Keyboard hides Textfield even if resizeToAvoidBottomInset is true

Unfortunately the Keyboard hides the TextField if it gets opened.
I also tried resizeToAvoidBottomInset: true, but it remains causing Render OverFlow error.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: getPrimaryDarkColor(),
resizeToAvoidBottomInset: true,
body: Stack(
children: [
Positioned(
bottom: -10,
child: Image.asset(
"assets/login_path_background.png",
width: 350,
color: getPrimaryColor().withOpacity(0.4),
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
How can I fix this?
wrap the body in a SingleChildScrollView
Wrap the Column in a SizedBox with device height as it’s height and the device width as it’s width. Then, inside that SizedBox, wrap the Column with a SingleChildScrollView. I had this same exact issue and just using a SingleChildScrollView does not work because the Stack item has no specific size or position. When you wrap the whole SingleChildScrollView in a SizedBox with the device size it works. Hope this helps!

how to make a widget to be on the bottom of the screen if using SliverStack?

as you can see at the image above, I have a red container stick on the top (right below the app bar). here is the code I use
CustomScrollView(
slivers: [
SliverAppBar(),
_buildStack(),
]
),
Widget _buildStack() {
return SliverStack(
children: [
// I have other widgets here ..
SliverPositioned(
bottom: 0, // <-- I have set the bottom to be zero
child: SliverToBoxAdapter(
child: _buildRedBox(),
),
],
)
}
Widget _buildRedBox() {
return Container(
width: double.infinity,
height: 50,
color: Colors.red,
);
}
I am using sliver tool package so I can access SliverStack and SliverPositioned.
as you can see, I have set the bottom to be zero. but the red box is still on the top. I need to make the red box at the bottom of the screen inside my SliverStack. how to do that ?
Use SliverFillRemaining widget instead of SliverPositioned widget.
SliverFillRemaining will automatically size itself to fill the space between the bottom of the last list item and the bottom of the viewport
SliverFillRemaining(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildRedBox(),
],
),
),

In Flutter, how can I have an adjusting vertical layout, a mix between column and listview behavior?

As far as I see, Column and ListView both have a very distinct usage when used for a base root layouting.
Column is used when the screen has few components (such as login screen). We can add some Expanded components to adjust white spaces in between, so when the keyboard is visible, the screen shrink to keep everything visible.
ListView is used when the screen has many components that potentially need scrolling. We can't use Expanded component in ListView. When using ListView, appearing keyboard does not change the white spaces, only change the size of outer ListView, while the inner content is wrapped in scroll view.
Now the problem is, how if I want to have screen like this:
When all the contents' combined vertical size is not longer than available height quota given from parent (in this case, screen's height), then the components behave like inside Column: expanding or shrinking to fill available white spaces according to rules set by Expanded.
When all the content's combined vertical size is longer than available height quota, then the components behave like inside ListView: all the possible expanding components will shrink into their minimum size (ignoring Expanded), and the screen is scrollable so user can see the rest of the screen below.
Is this possible to be done in Flutter? How?
EDIT: based on Reign's comment, I have isolated some code from SingleChildScrollView manual, but it looks like it still can't handle if its children contains Expanded.
Widget columnRoot({
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.spaceBetween,
AssetImage backgroundImage,
List<Widget> children
}) =>
LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) =>
SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: backgroundImage,
fit: BoxFit.cover),
color: Colors.white
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: mainAxisAlignment,
children: children
),
)
)
)
);
Widget content(BuildContext context) => columnRoot(children: [
Container(color: Colors.red, height: 100.0),
Expanded(Container(color: Colors.green)), // without this line, there's no layout error
Container(color: Colors.blue, height: 100.0),
]);
Error:
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I added some code you can test with also with some explanation.
Copy paste and run the code
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SingleChildScrollView( //Since setting it to scrollable, your widget Column with expanded children wont work as it supposed to be because it wont know its parent height
//Since its already scrollable `Expanded` will expand or shrink now based on it child widget (Expanded(child: SomeHeight widget)) refer: #10 example
child: IntrinsicHeight( //This will fix the expanded widget error
child: Container(
//Test remove this height
// height: 400, //But when you set its height before its parent scroll widget, `Expanded` will expand based on its available space
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: [
Container(color: Colors.red, height: 100.0),
//#10
//Experiment with this
Expanded(
child: Container(
color: Colors.purple,
// height: 100.0, //initialized height, remove parent container height: 400
// child: Text("This is also considered as min height"),
),
),
Container(color: Colors.blue, height: 100.0),
],
),
),
),
),
),
);
}
}

Flutter: How to adjust the height of a container as the maximum height of its sibling in a row

I have two widgets in a row. The first widget is a black line with width 5.0, the second widget is a text widget whose size may vary according to the content. I want the first container to have the same height as of the second widget
One way is to make both widget child of an IntrinsicHeight widget and then declare the height of the first container as double.infinity. This should solve your problem. Example code is given below:
IntrinsicHeight(
child: Row(
children: <Widget>[
Container( //this is the first container
height: double.infinity
),
secondWidget(
)
],
)
Let me know if you have further query. Happy coding!
You can use Expanded widget. It divides siblings to the same height or width.
here is the code:
Row(
children: <Widget>[
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.green,
),
)
And here is the result:
That is so easy. I wish it could help.