SingleChildScrollView show white - flutter

i need to fix overflowed pixel, but when i use SingleChildScrollView, it just show white screen
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: buildAppBar(),
body:
Container(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(flex:5, child: Textselamatdatang(), ),
Flexible(flex:4, child:
Container(
child: Column(
children: <Widget>[
Loginformcontrainer(),
SizedBox(height: 30,),
Loginbutton()
],
),
)
) ),
],
),
),
),
);
}

This is for your Flexibles Widgets . In SingleChildScrollView you should define height for objects and you can't use Expanded or Flexible Widget.
I removed Your Flexible Widgets and your code works fine

Related

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))
]),
),
);
}

How to center content on screen and scroll if it overflows

I have as screen that is centered using:
SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: Center(
child: ...,
),
),
],
),
)
But if the content is larger than the screen size, it will overflow. How can I keep the content centered, but at the same time start scrolling if it overflows?
You could use ListView widget and then put your content into it's children
Like so:
SafeArea(
child: ListView(
children: <Widget>[
Expanded(
children: <Widget>[
Center(
child: ...,
),
]
),
],
),
)
Replace your column with a ListView.
Following #Tembero's logic, I added a shrinkWraped ListView, removed the Expanded, and wrapped the ListView in a Center widget, so now it behaves exactly as expected:
SafeArea(
child: Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Center(
child: ...
),
],
),
),
)

Flutter avoiding resize screen when i have TextFormField into PageView

in this simplified code i have two TextFormField into one of flutter PageView pages, that they are into another class which that extended from Container, not any Scaffold, now when i click into one of this TextFormFields, resizeToAvoidBottom* don't work in my code
Widget build(BuildContext context) {
return Consumer<ThemeManager>(builder: (context, theme, child) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
key: _scaffoldKey,
backgroundColor: theme.accentColor,
resizeToAvoidBottomPadding: false,
resizeToAvoidBottomInset: false,
body: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (overScroll) {
overScroll.disallowGlow();
return false;
},
child: Container(
width: double.infinity,
height: double.infinity,
child: IntrinsicHeight(
child: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 50,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
BuildLoginHeaderScreen(theme: theme),
Expanded(
child: PageView(
controller: _pageController,
children: <Widget>[
... // contains two TextFormFields
],
),
),
],
),
),
],
),
),
),
),
),
);
});
}
You can go around using resizeToAvoidBottomPadding by wrapping appropriate part of your code with SingleChildScrollView. For example
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
BuildLoginHeaderScreen(theme: theme),
Expanded(
child: PageView(
controller: _pageController,
children: <Widget>[
... // contains two TextFormFields
],
),
),
],
),
),
This will prevent pixel overflow when the keyboard reduces the view area.

Can't find correct layout option for how to use ListView in a custom Widget

I am trying to extract re-use a simple widget that is then referenced in parent widget. The custom widget simply uses a row to layout a textField and a button, and below this I Want to have a listview showing items. I then embed in the customwidget in parent, but it continually throws Error. I have not figured out how to get the custom widget working where I can use ListView or column layout inside. Below is the 2 simplified widgets that demo the issue.
Here is the parent widget, which is where I call the custom widget PlayListControl()
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
drawer: SideDrawer(),
);
}
}
And here is the playlistcontrol widget.
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
);
}
}
No matter what I try, it always complains about layout issue related to height. I would have thought wrapping the ListView in Expanded would solve the issue, but it doesn't. Only if I use a container and specify height do I not get the errors, but I want to use whatever available space there is.
How can I get this playlistcontrol() widget to properly render inside a parent control?
you forgot to wrap the first container of PlayListControl in Expanded widget..
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
));
}
}
class PlayListControl extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
),
);
}
}

How to position a Widget at the bottom of a SingleChildScrollView?

I need to use SingleChildScrollView in order to be able to use keyboard_actions so that i can put a "Done" button on top of the keyboard in iOS (using a numeric keyboard at the moment)
The SingleChildScrollView will have a column as a child and then a button to be placed at the bottom. I tried using LayoutBuilder to enforce a height to the SingleChildScrollView.
LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(),
// Spacer() ?
FlatButton()
])));
});
I tried using the BoxConstraints with the maxHeight attribute, but ultimately the widget wouldn't scrooll up when the keyboard appeared.
Side note: the Scaffold has both resizeToAvoidBottomInset and resizeToAvoidBottomPadding set to true (the default value)
The issue with SingleChildScrollView is that it shrikwrap it's children.
So to have auto size widget in between - we need to use MediaQuery to get the screen height & SizedBox to expand - SingleChildScrollView.
Here Button will be at bottom of screen.
working Code:
double height = MediaQuery.of(context).size.height;
SingleChildScrollView(
child: SizedBox(
height: height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
children: <Widget>[
Text('Dummy'),
Text('Dummy'),
Text('Dummy'),
],
),
Spacer(),
FlatButton(
onPressed: () {},
child: Text('Demo'),
)
])),
)
The chosen answer doesn't really work, as using a SizedBox restrict the max size of the Column to the height of the screen, so you can't put as many widgets as you want in it (or they will go off-screen without beeing scrollable).
This solution will work no matter of many widgets are in the column:
https://github.com/flutter/flutter/issues/18711#issuecomment-505791677
Important note: It will only work if the widgets in the column have a fixed height (for example TextInputField does NOT have a fixed height). If they have variable a height, wrap them with a Container of fixed height.
I just copied and pasted here the best solution I found, quoted by #Quentin, elaborated by #NikitaZhelonkin in issue 18711 of Flutter on Github. Simply the perfect solution!
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppBar'),
),
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Text('header'),
Expanded(
child: Container(
color: Colors.green,
child: Text('body'),
),
),
Text('footer'),
]
),
)
)
);
})
);
}
}
You may use this workaround appraoch also, You can use padding attribute in SingleChildScrollView like this:
SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),
while height is the distance far away from top.
You can also use this line to get mobile screen height:
double height = MediaQuery.of(context).size.height;
The best solution I have found for myself.
Center the widgets and push them from top to bottom with padding.
return Scaffold(
resizeToAvoidBottomInset: true,
//resizeToAvoidBottomPadding: false,
backgroundColor: PrimaryColor,
body: Center(
SingleChildScrollView(child:
_body())));
Widget _body() {
return Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial !=
StateReqVM.Processing,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
...
...
...
],
)),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial ==
StateReqVM.Processing,
child: CircularProgressIndicator()),
Text(
'',
style: Theme.of(context).textTheme.headline4,
),
],
)
);
}