Related
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',
),
],
);
}
I am trying to display a container with some designs if it gets some data from firestore but if there is no data from firestore I want it to show a text saying no data from firestore, but it is not working and I'm getting errors.
...............................................................................................................................
below is the code, is this correct? getStoriesFunction:
Widget _getStories() {
Live users;
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: getStory(users),
);
}
Widget getStory(Live user) {
return Container(
margin: EdgeInsets.all(12),
child: Column(
children: <Widget>[
user.isLive == true
? Container(
height: 55,
width: 55,
child: GestureDetector(
onTap: () {
// Join function
onJoin(
channelName: user.displayName,
channelId: user.channelId,
displayName: displayName,
hostImage: user.image,
userImage: image);
},
child: Stack(
alignment: Alignment(0, 0),
children: <Widget>[
Container(
height: 60,
width: 60,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.red,
Colors.redAccent,
Colors.red
],
begin: Alignment.topLeft,
end: Alignment.bottomRight)),
),
),
Container(
height: 55.5,
width: 55.5,
child: CircleAvatar(
backgroundColor: Colors.black,
),
),
CachedNetworkImage(
imageUrl: user.image,
imageBuilder: (context, imageProvider) => Container(
width: 52.0,
height: 52.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover),
),
),
),
Container(
height: 70,
width: 70,
alignment: Alignment.bottomCenter,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
height: 17,
width: 25,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(
Radius.circular(
4.0) // <--- border radius here
),
gradient: LinearGradient(
colors: [Colors.black, Colors.black],
begin: Alignment.centerLeft,
end: Alignment.centerRight),
),
),
Container(
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(
Radius.circular(
2.0) // <--- border radius here
),
gradient: LinearGradient(
colors: [
Colors.red,
Colors.redAccent
],
begin: Alignment.centerLeft,
end: Alignment.centerRight),
),
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Text(
'LIVE',
style: TextStyle(
fontSize: 7,
color: Colors.white,
fontWeight: FontWeight.bold),
),
)),
],
))
],
),
))
: Text('No data in firestore',
style: TextStyle(
color: Colors.black,
fontSize: 12,
))
],
));
}
I have corrected you code and tested in the DartPad and work well for me. You can test to just copy and pase. It something wrong with user data from the firebase looks like bool isLive always true.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// Fake user data
bool userExist = false;
void _toggleUserState() {
setState(() => userExist = !userExist);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_getStories(userExist),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleUserState,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
Widget _getStories(bool user) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: getStory(user),
);
}
Widget getStory(bool user) {
return Container(
margin: EdgeInsets.all(12),
child: user == true
? Column(
children: <Widget>[
Container(
height: 55,
width: 55,
child: GestureDetector(
onTap: () {
// Join function
print('Join Function');
},
child: Stack(
alignment: Alignment(0, 0),
children: <Widget>[
Container(
height: 60,
width: 60,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
Colors.red,
Colors.redAccent,
Colors.red
],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
),
),
),
Container(
height: 55.5,
width: 55.5,
child: CircleAvatar(
backgroundColor: Colors.black,
),
),
// Cached Image container here.
Container(
height: 55.5,
width: 55.5,
child: Text('Cached Image'),
),
Container(
height: 70,
width: 70,
alignment: Alignment.bottomCenter,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
height: 17,
width: 25,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(
Radius.circular(4.0),
),
gradient: LinearGradient(
colors: [Colors.black, Colors.black],
begin: Alignment.centerLeft,
end: Alignment.centerRight),
),
),
Container(
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius:
BorderRadius.all(Radius.circular(2.0)),
gradient: LinearGradient(
colors: [Colors.red, Colors.redAccent],
begin: Alignment.centerLeft,
end: Alignment.centerRight),
),
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Text(
'LIVE',
style: TextStyle(
fontSize: 7,
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
],
),
)
],
),
),
)
],
)
: Text(
'No data in firestore',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
);
}
}
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,
)
);
I have an app screen that uses Checkboxes and a Drop down Menu. However, I have realised I'd coded it inside a StatelessWidget so I am unable to change the state when an option is selected. How do I get this working so that when a Checkbox is selected then it will display as being "checked" rather than empty?
I have tried pasting in my code into a Stateful Widget, however keep running into errors, as I am not totally sure on which parts should go where.
import 'package:carve_brace_app/model/activity.dart';
import 'package:flutter/material.dart';
class DetailPage extends StatelessWidget {
final Activity activity;
DetailPage({Key key, this.activity}) : super(key: key);
#override
Widget build(BuildContext context) {
final levelIndicator = Container(
child: Container(
child: LinearProgressIndicator(
backgroundColor: Color.fromRGBO(209, 224, 224, 0.2),
value: 2.0,
valueColor: AlwaysStoppedAnimation(Colors.green)),
),
);
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 120.0),
Container(
width: 90.0,
child: new Divider(color: Colors.green),
),
SizedBox(height: 10.0),
Text(
activity.activityName,
style: TextStyle(color: Colors.white, fontSize: 45.0),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"Last Run: 3-2-19\n"+
"Last Avg Strain: 34%\n"+
"Last Run Time: 00:45:23",
style: TextStyle(color: Colors.white),
))),
// Expanded(flex: 1, child: newRow)
],
),
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.45,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(33, 147, 176, 100),
Color.fromRGBO(109, 213, 237, 100)
],
),
),
child: Center(
child: topContentText,
),
),
Positioned(
left: 235.0,
top: 180.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: new CircleAvatar(
radius: 80.0,
backgroundImage: NetworkImage(activity.icon),
backgroundColor: Colors.white,
),
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContentText = Text(
"Config:",
style: TextStyle(fontSize: 18.0),
);
final mappedCheckbox = CheckboxListTile(
title: Text("Mapped"),
value: false,
onChanged: (newValue) { },
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final rtCheckBox = CheckboxListTile(
title: Text("Real-time Tracking"),
value: false,
onChanged: (newValue) { },
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final descriptionText = Text(
"Description:",
style: TextStyle(fontSize: 12.0),
);
final description = TextFormField(
decoration: InputDecoration(
hintText: 'Enter an activity description',
),
);
final scheduledFor = Text(
"Scheduled for:",
style: TextStyle(fontSize: 12.0),
);
final dropdown = new DropdownButton<String>(
items: <String>['Now (Default)', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
hint: Text("Now (Default)"),
onChanged: (_) {},
);
final readButton = Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
width: 170,//MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () => {},
color: Colors.lightBlue,
child:
Text("Start", style: TextStyle(color: Colors.white, fontSize: 20)),
));
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(40.0),
child: Center(
child: Column(
children: <Widget>[bottomContentText, mappedCheckbox, rtCheckBox, descriptionText, description, Text("\n"), scheduledFor, dropdown, readButton],
),
),
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
}
}
Hover on to the StatelessWidget class and use
Android Studio:
Mac: option + enter
Windows: alt + enter
Visual Studio Code:
Mac: cmd + .
Windows: ctrl + .
Output (Your solution):
Here is the working code.
class DetailPage extends StatefulWidget {
final Activity activity;
DetailPage({Key key, this.activity}) : super(key: key);
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
bool _tracking = false, _mapped = false; // you need this
String _schedule;
#override
Widget build(BuildContext context) {
final levelIndicator = Container(
child: Container(
child: LinearProgressIndicator(backgroundColor: Color.fromRGBO(209, 224, 224, 0.2), value: 2.0, valueColor: AlwaysStoppedAnimation(Colors.green)),
),
);
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 120.0),
Container(
width: 90.0,
child: Divider(color: Colors.green),
),
SizedBox(height: 10.0),
Text(
widget.activity.activityName,
style: TextStyle(color: Colors.white, fontSize: 45.0),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"Last Run: 3-2-19\n" + "Last Avg Strain: 34%\n" + "Last Run Time: 00:45:23",
style: TextStyle(color: Colors.white),
))),
// Expanded(flex: 1, child: newRow)
],
),
],
);
final topContent = Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.45,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color.fromRGBO(33, 147, 176, 100), Color.fromRGBO(109, 213, 237, 100)],
),
),
child: Center(
child: topContentText,
),
),
Positioned(
left: 235.0,
top: 180.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: CircleAvatar(
radius: 80.0,
backgroundColor: Colors.white,
),
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContentText = Text(
"Config:",
style: TextStyle(fontSize: 18.0),
);
final mappedCheckbox = CheckboxListTile(
title: Text("Mapped"),
value: _mapped,
onChanged: (newValue) => setState(() => _mapped = newValue),
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final rtCheckBox = CheckboxListTile(
title: Text("Real-time Tracking"),
value: _tracking,
onChanged: (newValue) => setState(() => _tracking = newValue),
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
);
final descriptionText = Text(
"Description:",
style: TextStyle(fontSize: 12.0),
);
final description = TextFormField(
decoration: InputDecoration(
hintText: 'Enter an activity description',
),
);
final scheduledFor = Text(
"Scheduled for:",
style: TextStyle(fontSize: 12.0),
);
final dropdown = DropdownButton<String>(
value: _schedule,
items: <String>['Now (Default)', 'B', 'C', 'D'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
hint: Text("Now (Default)"),
onChanged: (newValue) {
setState(() {
_schedule = newValue;
});
},
);
final readButton = Container(
padding: EdgeInsets.symmetric(vertical: 16.0),
width: 170, //MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () => {},
color: Colors.lightBlue,
child: Text("Start", style: TextStyle(color: Colors.white, fontSize: 20)),
));
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(40.0),
child: Center(
child: Column(
children: <Widget>[bottomContentText, mappedCheckbox, rtCheckBox, descriptionText, description, Text("\n"), scheduledFor, dropdown, readButton],
),
),
);
return Scaffold(
body: Column(
children: <Widget>[topContent, bottomContent],
),
);
}
}
For VSCode (Visual Studio Code) use ctrl + '.' keys while the cursor on the stateless widget to convert it to stateful widget.
You could use intellij's or vscode shortcut by hitting alt + enter or selecting the bulb icon while your cursor is on the name of the stateless widget then select convert to stateful widget
For Android Studio in Mac:
1.Place the marker on the Stateless widget name
2.Hit Alt+Enter
3.Select Convert to Stateful widget
4.Configure your Stateful widget based on your requirements
Adding a solution for Android Studio since I didn't find one here.
Place the marker on the Stateless widget name:
Hit Alt+Enter
Select Convert to Stateful widget
Configure your Stateful widget based on your requirements
I have the below display and data is coming from JSON. But, the problem is data is showing only on one column all the time. How do I make sure it is like left to right till all the data is filled?
this is the code. As you can see that I am creating a card and having the rest of the details inside the card and then in another code I am looping till I have all the JSON details.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:elegal_dart/models/items.dart';
import 'package:elegal_dart/services/api.dart';
class LostPage extends StatefulWidget {
#override
_LostPage createState() => new _LostPage();
}
class _LostPage extends State<LostPage> {
List<Item> _items = [];
#override
void initState() {
super.initState();
_loadLostItems();
}
_loadLostItems() async {
String fileData =
await DefaultAssetBundle.of(context).loadString("assets/items.json");
setState(() {
_items = ItemApi.allItemsFromJson(fileData);
});
print(_items.toString());
}
Widget _buildLostItems(BuildContext context, int index) {
Item item = _items[index];
return GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: <Widget>[
Card(
child: Column(
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.height / 2.5,
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
item.item_DispPic),
fit: BoxFit.cover),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: FractionalOffset.topLeft,
child: CircleAvatar(
backgroundColor: Colors.redAccent,
radius: 15.0,
child: Text(
"NEW",
textScaleFactor: 0.5,
),
),
),
),
Align(
alignment: FractionalOffset.topRight,
child: Container(
color: Colors.blueAccent,
height: 35.0,
width: 35.0,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_circle),
Text(
"1P",
textScaleFactor: 0.5,
),
],
),
),
),
),
],
),
),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
alignment: FractionalOffset.bottomCenter,
child: Text(
"MEGADISH",
style: TextStyle(
fontWeight: FontWeight.w700,
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlatButton(
child: Text(
"Add To Cart",
style: TextStyle(color: Colors.grey[500]),
),
onPressed: () => null,
),
Text(
"\$5",
style: TextStyle(color: Colors.grey[500]),
)
],
)
],
),
),
],
);
}
Widget _getAppTitleWidget() {
return new Text(
'Lost Items',
style: new TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 32.0,
),
);
}
Widget _buildBody() {
return new Container(
margin: const EdgeInsets.fromLTRB(
8.0, // A left margin of 8.0
56.0, // A top margin of 56.0
8.0, // A right margin of 8.0
0.0 // A bottom margin of 0.0
),
child: new Column(
// A column widget can have several
// widgets that are placed in a top down fashion
children: <Widget>[
//_getAppTitleWidget(),
_getListViewWidget()
],
),
);
}
Future<Null> refresh() {
_loadLostItems();
return new Future<Null>.value();
}
Widget _getListViewWidget() {
return new Flexible(
child: new RefreshIndicator(
onRefresh: refresh,
child: new ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: _items.length,
itemBuilder: _buildLostItems
)
)
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.blue,
body: _buildBody(),
);
}
}
I made it work as follows (if I understood correctly your objective which was to display as a 2-column grid).
It also scrolls, which with your code did not work.
#override
Widget build(BuildContext context) {
return new SafeArea(
top: false,
bottom: false,
child: new Scaffold(
appBar: new AppBar(
title: _getAppTitleWidget(),
),
backgroundColor: Colors.blue,
body: _buildBody(),
),
);
}
Widget _buildBody() {
int numberOfColumns = 2;
return new Container(
padding: const EdgeInsets.all(8.0),
child: new GridView.builder(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: numberOfColumns),
itemBuilder: _buildLostItems,
itemCount: _items.length,
),
);
}
Widget _buildLostItems(BuildContext context, int index) {
Item item = _items[index];
return new GridTile(
child: Card(
child: Column(
// mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.height / 2.5,
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
item.item_DispPic),
fit: BoxFit.cover),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: FractionalOffset.topLeft,
child: CircleAvatar(
backgroundColor: Colors.redAccent,
radius: 15.0,
child: Text(
"NEW",
textScaleFactor: 0.5,
),
),
),
),
Align(
alignment: FractionalOffset.topRight,
child: Container(
color: Colors.blueAccent,
height: 35.0,
width: 35.0,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_circle),
Text(
"1P",
textScaleFactor: 0.5,
),
],
),
),
),
),
],
),
),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
alignment: FractionalOffset.bottomCenter,
child: Text(
"MEGADISH",
style: TextStyle(
fontWeight: FontWeight.w700,
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FlatButton(
child: Text(
"Add To Cart",
style: TextStyle(color: Colors.grey[500]),
),
onPressed: () => null,
),
Text(
"\$5",
style: TextStyle(color: Colors.grey[500]),
)
],
)
],
),
),
);
}
Here is the output:
Hope this helps.
***** Refer to other solution *****
Could you please try the following?
Update the numberOfColumns as you wish.
int numberOfColumns = 2;
List<Item> _items = <Item>[ ... ];
#override
Widget build(BuildContext context){
GridView gridView = new GridView.builder(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: numberOfColumns),
itemBuilder: _buildLostItems,
itemCount: _items.length,
);
return new SafeArea(
top: false,
bottom: false,
child: new Scaffold(
appBar: new AppBar(
title: new Text('title'),
),
body: gridView,
),
);
}
_buildLostItems(BuildContext context, int index){
Item item = _items[index];
return new Card(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Expanded(
child: new Stack(
fit: StackFit.expand,
children: <Widget>[
new Container(
height: MediaQuery.of(context).size.height / 4,
width: MediaQuery.of(context).size.height / 2.5,
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(item.item_DispPic),
fit: BoxFit.cover),
),
),
),
),
new Padding(
padding: const EdgeInsets.all(8.0),
child: new Align(
alignment: FractionalOffset.topLeft,
child: new CircleAvatar(
backgroundColor: Colors.redAccent,
radius: 15.0,
child: const Text(
"NEW",
textScaleFactor: 0.5,
),
),
),
),
],
),
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new FlatButton(
child: new Text(
"Add To Cart",
style: new TextStyle(color: Colors.grey[500]),
),
onPressed: () {},
),
new Text(
"\$5",
style: new TextStyle(color: Colors.grey[500]),
)
],
),
],
),
);
}