Flutter how to add a Expandable menu item inside navigation drawer? - dart

I want to add expandable menu to drawer items of flutter. How can I achieve this functionality in flutter. Please just point me in the correct direction if there is any example or blog.

You have to pass the drawers child property a ListView, and in that ListView you can then use an ExpansionTile. That would look something like this:
Drawer(
child: ListView(
children: <Widget>[
ExpansionTile(
title: Text("Expansion Title"),
children: <Widget>[Text("children 1"), Text("children 2")],
)
],
),
);

You have to pass the drawers child property a ListView, and in that ListView you can then use an ExpansionTile. That would look something like this:
ExpansionTile(
title: Text('Categories'),
leading: Icon(Icons.view_list),
children: <Widget>[
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Shalwar kameez"))))),
onTap: (){},
),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Sherwani."))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Sindhi Ajrak or Cap."))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width:250,
height: 40,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Punjabi kurta and tehmat."))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Saraiki Turban"))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Saraiki Kurta."))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Peshawari Turban."))))),
onTap: (){},),
SizedBox(height: 7,),
GestureDetector(
child: SizedBox(
width: 250,
height: 35,
child: Container(
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(15),
),
child: Card(child: Center(child: Text("Lehenga Choli"))))),
onTap: (){},),
],

My solution:
ExpansionTile(
leading: Icon(
Icons.settings,
color: headingcolor,
),
trailing: Icon(
Icons.arrow_forward_ios_rounded,
size: 10.0,
color: defaultcolor,
),
title: Text(
"Settings",
style: TextStyle(
color: headingcolor,
),
),
children: <Widget>[
DrawerListTile(
title: "Terms",
svgSrc: Icon(
Icons.rule_sharp,
color: headingcolor,
),
press: () {
Get.offAll(
() => SettingsScreenMainTerms(),
duration: Duration(milliseconds: 400), //
transition: Transition.zoom,
);
},
),
DrawerListTile(
title: "Notifications",
svgSrc: Icon(
Icons.edit_notifications_rounded,
color: headingcolor,
),
press: () {
Get.offAll(
() => SettingsScreenMainNotifications(),
duration: Duration(milliseconds: 400), //
transition: Transition.zoom,
);
},
),
],
),

Related

Flutter other widget doesn`t show when I call my new created custom widget

Hello when ever I tried to call the bottombar widget (the custom widget that I created) The other widget elements dissapears
here is the home_page.dart code:
import 'package:clothing_app/utils/bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:line_awesome_icons/line_awesome_icons.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int buttonSelected = 1;
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
bottomNavigationBar: BottomBar(),
appBar: AppBar(
elevation: 0,
backgroundColor: SCAFFOLD_BG_COLOR,
leading: IconButton(
onPressed: () {},
icon: Icon(
LineAwesomeIcons.bars,
color: MAIN_BLACK_COLOR,
),
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
LineAwesomeIcons.search,
color: MAIN_BLACK_COLOR,
),
),
],
),
body: Column(
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(
vertical: 12, horizontal: 16),
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
_topSlideItem(),
SizedBox(
width: 24,
),
_topSlideItem(),
SizedBox(
width: 24,
),
_topSlideItem(),
SizedBox(
width: 24,
),
_topSlideItem(),
SizedBox(
width: 24,
),
_topSlideItem(),
SizedBox(
width: 24,
),
_topSlideItem(),
],
),
),
),
],
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Best of the week',
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold),
),
SizedBox(
height: 24,
),
verticalSlideItem(),
SizedBox(height: 16),
verticalSlideItem(),
SizedBox(height: 16),
verticalSlideItem(),
SizedBox(height: 16),
verticalSlideItem(),
SizedBox(height: 16),
verticalSlideItem(),
SizedBox(height: 16),
verticalSlideItem(),
],
),
)
],
),
),
),
],
),
),
);
}
Widget _topSlideItem() {
return Material(
borderRadius: BorderRadius.circular(32),
color: Colors.white,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 32),
width: MediaQuery.of(context).size.width * .55,
child: Row(
children: <Widget>[
Image.asset(
'assets/img.jpeg',
height: 140,
width: 50,
fit: BoxFit.fitHeight,
),
SizedBox(width: 24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Flower patterned khaki dress',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 12,
),
Row(
children: <Widget>[
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(4),
),
),
SizedBox(
width: 8,
),
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(4),
),
),
SizedBox(
width: 8,
),
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(4),
),
)
],
),
SizedBox(
height: 12,
),
Text(
'\$89,99',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(180, 184, 190, 1),
),
),
],
),
)
],
),
),
);
}
Widget verticalSlideItem() {
return Material(
borderRadius: BorderRadius.circular(32),
color: Colors.transparent,
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(24)),
child: Center(
child: Image.asset(
'assets/img.jpeg',
height: 110,
width: 80,
fit: BoxFit.fitHeight,
),
),
),
SizedBox(width: 24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Flower patterned\nkhaki dress',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 12,
),
Row(
children: <Widget>[
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(4),
),
),
SizedBox(
width: 8,
),
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(4),
),
),
SizedBox(
width: 8,
),
Container(
height: 12,
width: 12,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(4),
),
)
],
),
SizedBox(
height: 12,
),
Text(
'\$89,99',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(180, 184, 190, 1),
),
),
],
),
)
],
),
),
);
}
}
here is the custom widget I created (bottom_bar.dart);
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.call),
label: 'Calls',
),
BottomNavigationBarItem(
icon: Icon(Icons.camera),
label: 'Camera',
),
BottomNavigationBarItem(
icon: Icon(Icons.chat),
label: 'Chats',
),
],
),
),
);
}
}
here is the main.dart file;
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: 'Cera'),
home: HomePage(),
);
}
}
here is the image when I call the bottom navigationbar;
and here is an image when I remove the bottom navigationbar code line (bottomNavigationBar: BottomBar(),);
You are wrapping your custom BottomNavigationBar with Scaffold and it covers you HomePage Scaffold, so that's why the other widgets couldn't be shown.
Remove the Scaffold from the custom BottomNavigationBar:
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.call),
label: 'Calls',
),
BottomNavigationBarItem(
icon: Icon(Icons.camera),
label: 'Camera',
),
BottomNavigationBarItem(
icon: Icon(Icons.chat),
label: 'Chats',
),
],
);
}

RenderCustomMultiChildLayoutBox object was given an infinite size during layout error

I keep getting the error as mentioned when I try to load LessonPage. What is happening is that I have a RootPage which checks if a user is signed in, if he is the RootPage will show the LessonPage but if he is not, it will show the LoginScreen which when the user logs in, will invoke a callback function to RootPage _onLoggedIn()so as to switch pages to the LessonPage.
Update: I found out that the error is also logged when I load the app (i.e. the app opens to a LoginScreen), however I see my login screen instead of a blank screen. I've appended my LoginScreen code below for reference
Root Page:
class RootPage extends StatefulWidget {
RootPage({this.auth});
final BaseAuth auth;
#override
State<StatefulWidget> createState() => new _RootPageState();
}
enum AuthStatus {
NOT_DETERMINED,
NOT_LOGGED_IN,
LOGGED_IN,
}
class _RootPageState extends State<RootPage> {
AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
String _userId = "";
#override
void initState() {
super.initState();
widget.auth.getCurrentUser().then((user) {
setState(() {
if (user != null) {
_userId = user?.uid;
}
authStatus =
user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
});
});
}
void _onLoggedIn() {
widget.auth.getCurrentUser().then((user){
setState(() {
_userId = user.uid.toString();
});
});
setState(() {
authStatus = AuthStatus.LOGGED_IN;
});
}
void _onSignedOut() {
setState(() {
authStatus = AuthStatus.NOT_LOGGED_IN;
_userId = "";
});
}
Widget _buildWaitingScreen() {
return Scaffold(
body: Container(
alignment: Alignment.center,
child:
ColorLoader5(
dotOneColor: Colors.blueGrey[600],
dotTwoColor: Colors.blueGrey[700],
dotThreeColor: Colors.blueGrey[800],
dotType: DotType.circle,
dotIcon: Icon(Icons.adjust),
duration: Duration(seconds: 1),
),
),
);
}
#override
Widget build(BuildContext context) {
switch (authStatus) {
case AuthStatus.NOT_DETERMINED:
return _buildWaitingScreen();
break;
case AuthStatus.NOT_LOGGED_IN:
return new LoginScreen(
auth: widget.auth,
onSignedIn: _onLoggedIn,
);
break;
case AuthStatus.LOGGED_IN:
if (_userId.length > 0 && _userId != null) {
return new Container(child: SingleChildScrollView(child: LessonPage(
title: LESSON_PAGE_TITLE,
userId: _userId,
auth: widget.auth,
onSignedOut: _onSignedOut,
)));
} else return _buildWaitingScreen();
break;
default:
return _buildWaitingScreen();
}
}
}
Lesson Page:
class LessonPage extends StatefulWidget {
LessonPage({Key key, this.auth, this.userId, this.onSignedOut, this.title}) : super(key: key);
final String title;
final BaseAuth auth;
final VoidCallback onSignedOut;
final String userId;
#override
_LessonPageState createState() => _LessonPageState();
}
class _LessonPageState extends State<LessonPage> {
List lessons;
#override
void initState() {
lessons = StaticMethods.getLessons();
super.initState();
}
#override
Widget build(BuildContext context) {
ListTile makeListTile(Lesson lesson) => ListTile(
contentPadding:
EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
leading: Container(
padding: EdgeInsets.only(right: 12.0),
decoration: new BoxDecoration(
border: new Border(
right: new BorderSide(width: 1.0, color: Colors.white24))),
child: IconButton(
icon: Icon(Icons.file_download, color: Colors.white),
onPressed: (){},
),
),
title: Text(
lesson.title,
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
subtitle: Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: LinearProgressIndicator(
backgroundColor: Color.fromRGBO(209, 224, 224, 0.2),
value: lesson.indicatorValue,
valueColor: AlwaysStoppedAnimation(Colors.green)),
)),
Expanded(
flex: 4,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(lesson.level,
style: TextStyle(color: Colors.white))),
)
],
),
trailing:
Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 30.0),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(lesson: lesson)));
},
);
Card makeCard(Lesson lesson) => Card(
elevation: 8.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Container(
decoration: BoxDecoration(color: Color.fromRGBO(64, 75, 96, .9)),
child: makeListTile(lesson),
),
);
final makeBody = Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: lessons.length,
itemBuilder: (BuildContext context, int index) {
return makeCard(lessons[index]);
},
),
);
final makeBottom = Container(
height: 55.0,
child: BottomAppBar(
color: Color.fromRGBO(58, 66, 86, 1.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.school, color: Colors.white),
onPressed: () => StaticMethods.goToWidget(context, new LessonPage(title: LESSON_PAGE_TITLE)),
),
IconButton(
icon: Icon(Icons.flight_takeoff, color: Colors.white),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.account_box, color: Colors.white),
onPressed: () {},
)
],
),
),
);
final topAppBar = AppBar(
elevation: 0.1,
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
title: Text(widget.title),
automaticallyImplyLeading: false,
);
return Scaffold(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
appBar: topAppBar,
body: makeBody,
bottomNavigationBar: makeBottom,
);
}
}
LoginScreen Containers:
Widget OptionPage() {
return new Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Color.fromRGBO(58, 66, 86, 1.0),
image: DecorationImage(
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.1), BlendMode.dstATop),
image: AssetImage('assets/images/drones.jpg'),
fit: BoxFit.cover,
),
),
child: new Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 250.0),
child: Center(
child: Icon(
Icons.school,
color: Colors.white,
size: 40.0,
),
),
),
Container(
padding: EdgeInsets.only(top: 20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
LOGIN_SCREEN_TITLE,
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
],
),
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 30.0, right: 30.0, top: 150.0),
alignment: Alignment.center,
child: new Row(
children: <Widget>[
new Expanded(
child: new OutlineButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
color: Color.fromRGBO(58, 66, 86, 1.0),
highlightedBorderColor: Colors.white,
onPressed: () => gotoSignup(),
child: new Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Text(
LOGIN_SCREEN_SIGN_UP,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
],
),
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 30.0, right: 30.0, top: 30.0),
alignment: Alignment.center,
child: new Row(
children: <Widget>[
new Expanded(
child: new FlatButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0)),
color: Colors.white,
onPressed: () => gotoLogin(),
child: new Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Text(
LOGIN_SCREEN_LOGIN,
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(58, 66, 86, 1.0),
fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
],
),
),
],
),
);
}
Widget LoginPage() {
return new Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white,
image: DecorationImage(
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.05), BlendMode.dstATop),
image: AssetImage('assets/images/drones.jpg'),
fit: BoxFit.cover,
),
),
child: new Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(120.0),
child: Center(
child: Icon(
Icons.school,
color: Color.fromRGBO(58, 66, 86, 1.0),
size: 50.0,
),
),
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text(
LOGIN_SCREEN_EMAIL,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextFormField( // LOGIN SCREEN EMAIL
maxLines: 1,
keyboardType: TextInputType.emailAddress,
autofocus: false,
textAlign: TextAlign.left,
decoration: InputDecoration(
icon: Icon(Icons.alternate_email),
hintText: LOGIN_SCREEN_EMAIL_HINT,
hintStyle: TextStyle(color: Colors.grey),
),
validator: (value) => value.isEmpty ? LOGIN_SCREEN_EMAIL_WARNING : null,
onSaved: (value) => _email = value,
),
),
],
),
),
Divider(
height: 24.0,
color: Color(0x00000000),
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text(
LOGIN_SCREEN_PASSWORD,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextFormField( // LOGIN SCREEN PASSWORD
obscureText: true,
keyboardType: TextInputType.emailAddress,
maxLines: 1,
autofocus: false,
textAlign: TextAlign.left,
decoration: InputDecoration(
icon: Icon(Icons.lock_outline),
hintText: LOGIN_SCREEN_PASSWORD_HINT,
hintStyle: TextStyle(color: Colors.grey),
),
validator: (value) => value.isEmpty ? LOGIN_SCREEN_PASSWORD_WARNING : null,
onSaved: (value) => _password = value,
),
),
],
),
),
Divider(
height: 24.0,
color: Color(0x00000000),
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: new FlatButton(
child: new Text(
LOGIN_SCREEN_FORGOT_PASSWORD,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
textAlign: TextAlign.end,
),
onPressed: () => StaticMethods.locked(context),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 30.0, right: 30.0, top: 20.0),
alignment: Alignment.center,
child: new Row(
children: <Widget>[
new Expanded(
child: new FlatButton( // LOGIN SCREEN LOGIN BUTTON
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: Color.fromRGBO(58, 66, 86, 1.0),
onPressed: () => _validateAndSubmit(),
child: new Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Text(
LOGIN_SCREEN_LOGIN,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
],
),
),
Divider(
height: 25.0,
color: Color(0x00000000),
),
_showErrorMessage(),
Divider(
height: 25.0,
color: Color(0x00000000),
),
_showLoading(),
],
),
);
}
Widget SignupPage() {
return new Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.white,
image: DecorationImage(
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.05), BlendMode.dstATop),
image: AssetImage('assets/images/drones.jpg'),
fit: BoxFit.cover,
),
),
child: new Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(100.0),
child: Center(
child: Icon(
Icons.school,
color: Color.fromRGBO(58, 66, 86, 1.0),
size: 50.0,
),
),
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text(
LOGIN_SCREEN_EMAIL,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextField( //SIGNUP SCREEN EMAIL
obscureText: true,
textAlign: TextAlign.left,
decoration: InputDecoration(
hintText: LOGIN_SCREEN_EMAIL_HINT,
hintStyle: TextStyle(color: Colors.grey),
),
),
),
],
),
),
Divider(
height: 24.0,
color: Color(0x00000000),
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text(
LOGIN_SCREEN_PASSWORD,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextField( // SIGNUP SCREEN PASSWORD
obscureText: true,
textAlign: TextAlign.left,
decoration: InputDecoration(
hintText: LOGIN_SCREEN_PASSWORD_HINT,
hintStyle: TextStyle(color: Colors.grey),
),
),
),
],
),
),
Divider(
height: 24.0,
color: Color(0x00000000),
),
new Row(
children: <Widget>[
new Expanded(
child: new Padding(
padding: const EdgeInsets.only(left: 40.0),
child: new Text( // SIGNUP SCREEN CONFIRM PASSWORD
LOGIN_SCREEN_CONFIRM_PASSWORD,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 40.0, right: 40.0, top: 10.0),
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 0.0, right: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Expanded(
child: TextField(
obscureText: true,
textAlign: TextAlign.left,
decoration: InputDecoration(
hintText: LOGIN_SCREEN_PASSWORD_HINT,
hintStyle: TextStyle(color: Colors.grey),
),
),
),
],
),
),
Divider(
height: 24.0,
color: Color(0x00000000),
),
new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: new FlatButton(
child: new Text(
LOGIN_SCREEN_HAVE_ACCOUNT,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromRGBO(58, 66, 86, 1.0),
fontSize: 15.0,
),
textAlign: TextAlign.end,
),
onPressed: () => StaticMethods.locked(context),
),
),
],
),
new Container(
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(left: 30.0, right: 30.0, top: 50.0),
alignment: Alignment.center,
child: new Row(
children: <Widget>[
new Expanded(
child: new FlatButton( // SIGNUP SCREEN SIGN UP BUTTON
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: Color.fromRGBO(58, 66, 86, 1.0),
onPressed: () => StaticMethods.locked(context),
child: new Container(
padding: const EdgeInsets.symmetric(
vertical: 20.0,
horizontal: 20.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: Text(
LOGIN_SCREEN_SIGN_UP,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
),
],
),
),
],
),
);
}
PageController _controller = new PageController(initialPage: 1, viewportFraction: 1.0);
#override
Widget build(BuildContext context) {
_isIos = Theme.of(context).platform == TargetPlatform.iOS;
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: new Form (
key: _formKey,
child: PageView(
controller: _controller,
physics: new AlwaysScrollableScrollPhysics(),
children: <Widget>[LoginPage(), OptionPage(), SignupPage()],
scrollDirection: Axis.horizontal,
onPageChanged: (num){
switch (num) {
case 0:
setState(() {
_formKey.currentState.reset();
_errorMessage = "";
_formMode = FormMode.LOGIN;
});
break;
case 1:
setState(() {
_formKey.currentState.reset();
_errorMessage = "";
_formMode = FormMode.OPTIONS;
});
break;
case 2:
setState(() {
_formKey.currentState.reset();
_errorMessage = "";
_formMode = FormMode.SIGNUP;
});
break;
}
},
),
),
);
}
Error:
I/flutter (18510): The following assertion was thrown during performLayout():
I/flutter (18510): RenderCustomMultiChildLayoutBox object was given an infinite size during layout.
.....
In the error, it shows just a blank page instead of lesson page, and checking firebase I can see that a user logs in so I think it is some layout issue.
What I've tried:
RootPage (I still saw a blank screen):
return new LessonPage(
title: LESSON_PAGE_TITLE,
userId: _userId,
auth: widget.auth,
onSignedOut: _onSignedOut,
);
I tried to return a normal page instead of lesson page which just shows a loading animation which is already tested and works but still I see a blank page:
return _buildWaitingScreen();
LessonPage (still see blank page):
Widget makeBody(BuildContext context) => Container(
height: MediaQuery.of(context).size.height / 1.5,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: lessons.length,
itemBuilder: (BuildContext context, int index) {
return makeCard(lessons[index]);
},
),
);
return Scaffold(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
appBar: topAppBar,
body: makeBody(context),
bottomNavigationBar: makeBottom,
);
You dont need Container and SingleChildScrollView in below snippet:
return LessonPage(
title: LESSON_PAGE_TITLE,
userId: _userId,
auth: widget.auth,
onSignedOut: _onSignedOut,
);
If that didn't fix,
RenderCustomMultiChildLayoutBox object was given an infinite size during layout. means that you have used ListView or ScrollView or any other widget that has infinite size. In order to prevent this issue, wrap your makeBody list view with fixed size. If it is working you can use MediaQuery.of(context).size.height(gives device screen width) and adjest the size you want.
Ex:
Widget makeBody(BuildContext context) => Container(
height: MediaQuery.of(context).size.height / 1.5,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: lessons.length,
itemBuilder: (BuildContext context, int index) {
return makeCard(lessons[index]);
},
),
);
and call the method: body: makeBody(context),
Fix in RootPage:
return new Container(
height: MediaQuery.of(context).size.height,
child: LessonPage(
title: LESSON_PAGE_TITLE,
userId: _userId,
auth: widget.auth,
onSignedOut: _onSignedOut,
)
);

How do I add SingleChildScrollView to a column

I'm developing an app and was following a sample from this link and ran into a problem where it says bottom overflowed by xx pixels as shown below:
Now, I encountered this before and solved it by adding SingleChildScrollView as shown below:
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Academy',
theme: new ThemeData(
primaryColor: Color.fromRGBO(58, 66, 86, 1.0)
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: new Container(
child: SingleChildScrollView(
child: LoginScreen(),
)
),
),
);
}
How do I do it when I'm not using a container but a column instead ? As that is what I'm using in the image above (column at the bottom of code, where the author returns the scaffold):
class DetailPage extends StatelessWidget {
final Lesson lesson;
DetailPage({Key key, this.lesson}) : super(key: key);
#override
Widget build(BuildContext context) {
final levelIndicator = Container(
child: Container(
child: LinearProgressIndicator(
backgroundColor: Color.fromRGBO(209, 224, 224, 0.2),
value: lesson.indicatorValue,
valueColor: AlwaysStoppedAnimation(Colors.green)),
),
);
final coursePrice = Container(
padding: const EdgeInsets.all(7.0),
decoration: new BoxDecoration(
border: new Border.all(color: Colors.white),
borderRadius: BorderRadius.circular(5.0)),
child: new Text(
"\$" + lesson.price.toString(),
style: TextStyle(color: Colors.white),
),
);
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 120.0),
Icon(
Icons.directions_car,
color: Colors.white,
size: 40.0,
),
Container(
width: 90.0,
child: new Divider(color: Colors.green),
),
SizedBox(height: 10.0),
Text(
lesson.title,
style: TextStyle(color: Colors.white, fontSize: 45.0),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(flex: 1, child: levelIndicator),
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
lesson.level,
style: TextStyle(color: Colors.white),
))),
Expanded(flex: 1, child: coursePrice)
],
),
],
);
final topContent = Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0),
height: MediaQuery.of(context).size.height * 0.5,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/images/drones1.jpg"),
fit: BoxFit.cover,
),
)),
Container(
height: MediaQuery.of(context).size.height * 0.5,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: Center(
child: topContentText,
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContentText = Text(
lesson.content,
style: TextStyle(fontSize: 18.0),
);
final readButton = Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () => {},
color: Color.fromRGBO(58, 66, 86, 1.0),
child:
Text("TAKE THIS LESSON", style: TextStyle(color: Colors.white)),
));
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(40.0),
child: Center(
child: Column(
children: <Widget>[bottomContentText, readButton],
),
),
);
return Scaffold(
body: Column( //here is the column
children: <Widget>[topContent, bottomContent],
),
);
}
}
I tried these but it does not work, giving me the same result as before:
return Scaffold(
body: Container(child: SingleChildScrollView(child:Column(children: <Widget>[topContent, bottomContent],),),),
);
return Scaffold(
body: Column(
children: <Widget>[Expanded(child: Column(children: <Widget>[topContent, bottomContent],))],
),
);
return Scaffold(
body: SingleChildScrollView(child: Container(child:Column(children: <Widget>[topContent, bottomContent],),),),
);
My outcome when I tried this as suggested:
return Scaffold(
body: Column( //here is the column
children: <Widget>[Expanded(child: SingleChildScrollView(child: Text("Test"))), Text("Data")],
),
);
I solved it by adding the SingleChildScrollView to the following in topContent:
Container(
height: MediaQuery.of(context).size.height * 0.5,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: SingleChildScrollView(
child: Center(
child: topContentText,
),
),
),

How to align two buttons at the bottom of the Dialog in Flutter

Here's a mockup of the dialog I'm trying to create in Flutter:
Here's what I have so far:
I'm unable to position my two button's with rounded bottom corners at the bottom of the dialog so that it looks like in the mockup.
I was able to make those buttons fit within the Dialog width, without the stack, but then it would be positioned at the top.
Here's the code for the dialog:
SimpleDialog carDialog = SimpleDialog(
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
children: <Widget>[
Container(
height: 400,
child: Stack(
children: <Widget>[
Positioned(
bottom: 0,
child: IntrinsicWidth(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(6)),
color: Colors.lightBlueAccent,
),
height: 45,
child: Center(
child: Text(
allTranslations.text('wait_enroute').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(6)),
color: AppColors.action_button,
),
height: 45,
child: Center(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
allTranslations.text('new_order').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
),
],
),
),
),
],
),
),
],
);
showDialog(context: context, builder: (context) => carDialog);
I have found a working solution. It does not require the Stack widget, everything can be nested within a Column like so:
SimpleDialog carDialog = SimpleDialog(
contentPadding: EdgeInsets.all(0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: 400,
),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: InkWell(
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(bottomLeft: Radius.circular(6)),
color: Colors.lightBlueAccent,
),
height: 45,
child: Center(
child: Text(
allTranslations.text('wait_enroute').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(bottomRight: Radius.circular(6)),
color: AppColors.action_button,
),
height: 45,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
allTranslations.text('new_order').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
),
],
),
],
),
],
);
showDialog(context: context, builder: (context) => carDialog);
The result:
You can try this replacing with Row
LayoutBuilder(
builder:(BuildContext context, BoxConstraints constraints){
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
width : constraints.maxWidth/2
child:Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(6)),
color: Colors.lightBlueAccent,
),
height: 45,
child: Center(
child: Text(
allTranslations.text('wait_enroute').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
SizedBox(
width : constraints.maxWidth/2
child:Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(6)),
color: AppColors.action_button,
),
height: 45,
child: Center(
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
allTranslations.text('new_order').toUpperCase(),
textAlign: TextAlign.center,
style: Fonts.appFont(context,
bold: true, color: Colors.white),
),
),
),
),
),
],
);
}
),

Write text on the icon in flutter

And I am Using this code: how to set this kind of layout in flutter
Container(
height: 200.0,
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Center(
child: Stack(
children: <Widget>[
Icon(Icons.play_arrow, color: Colors.blue, size: 200.0,)
],
),
),
);
try this, you have to just make Stack alignment to center and add a Text in Stack array.
Container(
height: 200.0,
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Center(
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Icon(
Icons.play_arrow,
color: Colors.blue,
size: 200.0,
),
Text(
"Play",
style: TextStyle(fontSize: 18,color: Colors.white),
),
],
),
),
)

Resources