This function has a return type of 'Row', but doesn't end with a return statement - flutter

i am trying to retrieve data from firestore as dropdown list, got this tutorial and error show up, please help, totally new with flutter.
This function has a return type of 'Row', but doesn't end with a return statement.
Try adding a return statement, or changing the return type to 'void'.
here is the code :
class _MyHomePageState extends State<MyHomePage> {
var selectedCurrency, selectedType;
final GlobalKey<FormState> _formKeyValue = new GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(
Icons.edit,
color: Colors.white,
),
onPressed: () {}),
title: Container(
alignment: Alignment.center,
child: Text("Account Details",
style: TextStyle(
color: Colors.white,
)),
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.edit,
size: 20.0,
color: Colors.white,
),
onPressed: null,
),
],
),
body: Form(
key: _formKeyValue,
autovalidate: true,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
children: <Widget>[
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.edit,
size: 25.0,
color: Color(0xff11b719),
),
SizedBox(width: 50.0),
],
),
SizedBox(height: 40.0),
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("currency").snapshots(),
builder: (context, snapshot) {
}),
SizedBox(
height: 150.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
RaisedButton(
color: Color(0xff11b719),
textColor: Colors.white,
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text("Submit", style: TextStyle(fontSize: 24.0)),
],
)),
onPressed: () {},
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0))),
],
),
],
),
));
}
}

I'm totally new to Flutter myself, but it appears the method build of the MyHomePageState class does have a return statement. In fact, all the method body is wrapped inside that return statement:
Widget build(BuildContext context) {
return Scaffold(
...
)}
That build method returns a complete description of your page, including the Row you mentioned in your question deeply nested in structure:
return Scaffold(
...
body: Form(
...
child: new ListView(
...
children: <Widget>[
SizedBox(height: 20.0),
Row( <---------------- here it is
...
Or did I missed your point?

Related

The getter 'length' was called on null in flutter

I have added three streamBuilder on my homepage and all the StreamBuilders fetch different data from cloud firestore but i am getting 'The getter 'length' was called on null in flutter' . I have tried to look for a solution on the internet but all in vain. Am getting this error:
════════ Exception caught by widgets library ═══════════════════════════════════
The getter 'length' was called on null.
Receiver: null
Tried calling: length
The relevant error-causing widget was
StreamBuilder<List<Order>>
lib/…/home/home.dart:52
Here is my home.dart:
import 'package:flutter/material.dart';
import 'package:merza/models/orders.dart';
import 'package:merza/models/user.dart';
import 'package:merza/screens/home/items.dart';
import 'package:merza/screens/home/orders/delivered_order.dart';
import 'package:merza/screens/home/orders/order_status.dart';
import 'package:merza/screens/user/add_order.dart';
import 'package:merza/services/auth.dart';
import 'package:merza/services/databse.dart';
import 'package:merza/shared/grid.dart';
import 'package:intl/intl.dart';
import 'package:merza/shared/menus.dart';
import 'package:merza/shared/splash_screen.dart';
import 'package:provider/provider.dart';
import 'package:merza/screens/home/orders/orders_list.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'orders/orders_tile.dart';
class Home extends StatelessWidget {
//Auth
AuthService _auth = AuthService();
//Database
Database _db = Database();
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
if(user.uid == null){
Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false);
}else{
return StreamBuilder<UserData>(
stream: Database(uid: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
//Streambuilder for delivered orders
return StreamBuilder<List<Order>>(
stream: Database(receiver_nrc: userData.nrc, paramOne: 'payment_status', paramValue: 'unpaid').dataFetch,
builder: (context, snapshot2) {
String count_unpaid = snapshot2.data.length.toString();
if (snapshot2.hasData) {
return StreamBuilder <List<Order>>(
stream: Database(receiver_nrc: userData.nrc, paramOne: 'order_status', paramValue: 'delivered').dataFetch,
builder: (context, snapshot3) {
String count_awaiting = snapshot3.data.length.toString();
if (snapshot3.hasData) {
return StreamProvider<List<Order>>.value(
value: Database(receiver_nrc: userData.nrc).orders,
child: Scaffold(
appBar: LoggedBar(title: 'Merza',),
body: SingleChildScrollView(
child: Column(
children: [
Container(), // Required some widget in between to float AppBar
Container( // To take AppBar Size only
child: AppBar(
elevation: 0.0,
backgroundColor: Colors.white,
leading: IconButton(icon: Icon(Icons.home), color: Colors.green[900], onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => Home()));
},),
primary: false,
title: TextField(
decoration: InputDecoration(
hintText: "Search",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.green[900]))),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search, color: Colors.green[900]), onPressed: () {},),
],
),
),
Container(
color: Colors.green,
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
child: Text('A TRADING ZONE THAT PROMOTES SAFETY TRADING AND SECURE DIGITAL TRANSACTIONS', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Colors.white)),
), Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 130,
child: ListTile(
title: Image.network('https://madvertadvertising.com/media/merza/images/seller.jpeg'),
onTap: (){
// Navigator.push(context, MaterialPageRoute(builder: (context) => ItemsPage()));
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(width: 8),
],
),
],
),
),
),
Expanded(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 130,
child: ListTile(
title: Image.network('https://madvertadvertising.com/media/merza/images/delivery.jpeg'),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => AwaitingOrdersList(nrc: userData.nrc, paramValueOne: 'order_status', paramValueTwo: 'delivered', barTitle: 'Delivered', isStaff: userData.is_staff.toString(), allowStaffPrivaledges: 'no',)));
},
),
),
const SizedBox(width: 8),
],
),
),
),
],
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 130,
child: ListTile(
title: Image.network('https://madvertadvertising.com/media/merza/images/items.jpeg'),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => ItemsPage()));
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(width: 8),
],
),
],
),
),
),
Expanded(
child: Container(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 130,
child: ListTile(
title: Image.network('https://madvertadvertising.com/media/merza/images/payment.jpeg'),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => DeliverdordersList(nrc: userData.nrc, paramValueOne: 'payment_status', paramValueTwo: 'paid', barTitle: 'Paid orders',)));
}
,
),
),
const SizedBox(width: 8),
],
),
),
),
),
],
),
),
Text('My recent placed orders', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
Container(
child: OrdersList(),
),
SizedBox(height: 10.0),
],
),
),
drawer: DrawerLogged()
),
);
}else{
return LoadingScreenCustom(page:'home');
}
}
);
}else{
return LoadingScreenCustom(page:'home');
}
}
);
}else{
return LoadingScreenCustom(page:'home');
}
}
);
}
}
}
I don't know if it is a good practice to add multiple stream builders on the same page.
Put String count_unpaid = snapshot2.data.length.toString(); line inside the if (snapshot2.hasData) block.
Put String count_awaiting = snapshot3.data.length.toString(); line inside the if (snapshot3.hasData) block.

Updating part of a stateful widget

i'm very new to Flutter.
I have a stateful widget. Every time i click a counter, the whole build function runs and the results are updated.
But is there a way to make it a stateless widget and update only the relevant part somehow so i could avoid rebuilding the screen?
I have a stateful widget. Every time i click a counter, the whole build function runs and the results are updated.
But is there a way to make it a stateless widget and update only the relevant part somehow so i could avoid rebuilding the screen?
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home:Home(),
));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State {
int long = 0;
void increaseCounter(){
setState(() {
long++;
});
}
void decreaseCounter(){
if(long > 0) {
setState(() {
long--;
});
}
}
Text numberOfDeliveries(){
return Text(
'$long deliveries today',
style: TextStyle(
color:Colors.white,
fontSize: 24.0,
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text('Deliveries'),
backgroundColor: Colors.green,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child:Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0, horizontal: 0.0),
child: Text(
'Long',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32.0,
color: Colors.white,
),
),
),
),
Expanded(
child:
// is it possible to update this without running the whole build again?
numberOfDeliveries(),
),
Expanded(
child: Row(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 32.0, horizontal: 0.0),
color:Colors.blue[100],
child: FlatButton(
onPressed: (){
decreaseCounter();
},
child: Text('-'),
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 32.0, horizontal: 0.0),
color:Colors.blue[500],
),
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(vertical: 32.0, horizontal: 0.0),
color:Colors.blue[900],
child: FlatButton(
onPressed: (){
increaseCounter();
},
child: Text('+'),
),
),
),
],
),
),
],
),
),
),
Expanded(
child: Container(
color: Colors.blue[800],
child: Row(
children: [
Text('Bottom'),
],
),
),
),
],
),
);
}
}

Updating single item on a Listview.builder widget in Flutter

so I have a list of users that is in a Listview.builder widget but my issue is that when I try to update one item on the list all the other items update as well.
I have a button that shows "Add friend" when I click on the button the message should change to "Invited", I have a string variable that holds the message so when I click on the button the string is updated from "Add friend" to "Invited", now when I click on button all the other button values change as well.
Here is my code:
class Friends extends StatefulWidget{
_FriendsState createState() => _FriendsState();
}
class _FriendsState extends State<Friends>{
List<String> nameList = [];
String btnText;
#override
Widget build(BuildContext context) {
bool showFriendList = false;
return Scaffold(
appBar: AppBar(
title: Text('Friends'),
actions: <Widget>[
IconButton(
onPressed: (){
},
icon: Icon(Icons.check, color: Colors.white,),
)
],
),
body:
Padding(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
showFriendList? Column(
children: <Widget>[
Text('Find friends to add. Once they accept you can invite them to your challenge.', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16),),
SizedBox(height: 45,),
Container(
width: MediaQuery.of(context).size.width,
child: RaisedButton(
child: Text('GO AND FIND FRIENDS', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 14, color: Colors.white)),
onPressed: (){
setState(() {
showFriendList != showFriendList;
});
},
color: Theme.of(context).accentColor,
shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).accentColor),borderRadius: BorderRadius.circular(14)),
),
)
],
): Container(
height: MediaQuery.of(context).size.height,
child:friends(context) ,
)
],
) ,
)
);
}
Widget friends(BuildContext context){
return
ListView(
children: <Widget>[
Container(
margin: EdgeInsets.all(8),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white
),
child: TextField(
decoration:InputDecoration(
hintText: 'Enter User\'s name',
border: InputBorder.none,),
),
),
/* noRequest== true? SizedBox(height: 0,):friendRequest(context),
noRequest== true? SizedBox(height: 0,): Container(
margin: EdgeInsets.all(10),
height: 60,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment:CrossAxisAlignment.start,
children: <Widget>[Text('Your friends', style: TextStyle(fontSize: 16, color: Theme.of(context).textSelectionColor,)) ],),
),*/
Container(
height: 0.5,
color: Colors.grey,
),
ListView.builder(
shrinkWrap: true,
itemCount: users.length,
itemBuilder: (BuildContext context, int index){
return
Container(
padding: EdgeInsets.only(left: 6),
height:80 ,
child:
Column(
children: <Widget>[
Row(
children: <Widget>[
users[index].profileUrl != null? CircleAvatar(child: Image.asset(users[index].profileUrl),): Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white70,
shape: BoxShape.circle,
image: DecorationImage(
image:AssetImage('assets/plus.png') //NetworkImage(renderUrl ??'assets/img.png')
)
),
),
SizedBox(width: 30,),
Expanded(
flex: 1,
child:
Container(
child:
Row(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 12,),
users[index].fullName != null? Text( users[index].fullName, style: TextStyle(fontSize: 18)): Text('Anjelika Thompson', style: TextStyle(fontSize: 18),),
SizedBox(height: 12,),
Row(
//crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(child: Icon(Icons.location_on),alignment: Alignment.topLeft,),
SizedBox(width: 10,),
users[index].distance_KM.toString() != null ? Text( users[index].distance_KM.toString()):Text('48.7 km')
]),
],
),
],
)
),
),
SizedBox(width: 0,),
//Icon(Icons.check,color: Colors.red,size: 40,)
FlatButton(
child: Text(btnText==null? 'ADD FRIEND': btnText, style: TextStyle(color: Color(0xff7667e5)),),
onPressed: () {
nameList.add(users[index].fullName);
setState(() {
btnText = 'INVITED';
});
},
)
],
),
Container(
height: 0.5,
color: Colors.grey,
)
],
) ,
);
}
// final item = feeds[index];
)
],
);
}
}
From my class, I have a string value called "btnText" that I use to set the new value. but at the moment once I click on one button to change from "Add friend" to "Invited" all other button Text in the listview change as well.
Please I need help figuring out what is the problem
#Chidinma, you can add a check to see if user is in your nameList,
FlatButton(
child: Text(btnText==null || !nameList.contains(users[index].fullName) ? 'ADD FRIEND': btnText, style: TextStyle(color: Color(0xff7667e5)),),
onPressed: () {
nameList.add(users[index].fullName);
setState(() {
btnText = 'INVITED';
});
................
This is just to give you an idea. A better solution would be to create a selected column in users table and save selected state as bool value. If you don't have database then i'd recommend creating indexList like nameList and save the index of invited friends and check to see if index is in the indexList like i've done with the nameList instead.
Method
inviteButtonStateFunction(index){
for (var e in invitedPeopleListIndex) {
if(e == index){
return Text("Invited");
}
}
return Text("Invite");
}
Usage
child: TextButton(
onPressed: () {
if(invitedPeopleListIndex.contains(index)){
invitedPeopleListIndex.remove(index);
}else{
invitedPeopleListIndex.add(index);
}
print(invitedPeopleListIndex);
print(invitedPeopleList);
},
child: inviteButtonStateFunction(index), // Show the text here
)

Flutter, how to get rid of raisedButton bottom margin?

So I'm trying to remove the bottom margin of raisedButton so it will look like it is merged with the card below it.
here's what it looks like
here is my code
Expanded(
child: Card(
elevation: 5,
// shape:
// RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Apakah anak sudah bisa ... ?",
style: TextStyle(fontWeight: FontWeight.bold)),
),
],
),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
child: Text(
"Iya",
style: TextStyle(color: Colors.white),
),
color: Colors.green[300],
onPressed: () {}),
),
Expanded(
child: RaisedButton(
child: Text(
"Tidak",
style: TextStyle(color: Colors.white),
),
color: Colors.red[200],
onPressed: () {}))
],
)
],
),
),
)
or do you guys have any other alternative solution to achieve that?
You can explicitly set your Row height to match the height of your RaisedButton. Simply wrap it inside a Container and add the height attribute.
If you want to, you can access the default height by using Theme.of(context).buttonTheme.height. Theme.of returns the ThemeData used in the current context.
Here a minimal example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Test'),
Container(
height: Theme.of(context).buttonTheme.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Yes'),
color: Colors.green,
),
RaisedButton(
onPressed: (){},
child: Text('No'),
color: Colors.red,
)
],
),
),
],
)
),
),
)),
);
}
}
I had the same problem. NikasPor's answer didnt work for me, unfortunately. The way I fixed it is by seeting the crossAxisAlignment on the row to .stretch
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children:[ /* Buttons Here */]
)

Expanded() widget not working in listview

I'm new to flutter. I'm trying to render a page whose body contains Listview with multiple widgets.
_buildOrderDetails widget in the listview is widget that is build with listview.builder() , remaining are normal widgets.
The problem is page is not being scrolled .
When the body Listview is changed to column and _buildOrderDetails is given as child to the Expanded, the listview is limited to some extent of the page height and being scrolled. But when input is focused the page is overflowed
Widget build(BuildContext context){
return ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget child, MainModel model) {
return Scaffold(
appBar: AppBar(
title: Text('Order Details'),
actions: <Widget>[
IconButton(
onPressed: () {
model.addNewOrder();
},
icon: Icon(Icons.add),
),
BadgeIconButton(
itemCount: model.ordersCount,
badgeColor: Color.fromRGBO(37, 134, 16, 1.0),
badgeTextColor: Colors.white,
icon: Icon(Icons.shopping_cart, size: 30.0,),
onPressed: () {}
),
]
),
body: ListView(
children: [
Column(
children: [
_buildItemsTitle(),
Expanded(child: _buildOrderDetails(context, model)),
]
),
Card(
child: Column(
children:[
TextField(
decoration: InputDecoration(
labelText: 'Offer Code'
),
),
RaisedButton(
onPressed: (){},
child: Text('Apply'),
)
]
),
),
Card(child: _orderAmount(context, model),),
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: (){},
child: Text('Checkout',
style: TextStyle(
fontSize: 20.0,
color: Colors.white
)
),
)
]
),);});}}
Maybe it can help someone in the future, but the trick seems to be: use ListView + LimitedBox(maxHeight) + Column ...
ListView(
padding: EdgeInsets.zero,
shrinkWrap: true,
children: [
FocusTraversalGroup(
child: Form(
key: _formKey,
child: LimitedBox(
maxHeight: MediaQuery.of(context).size.height,
child: Column(
// mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(flex: 30), // Or Expanded
// More Widgets...
Spacer(flex: 70), // Or Expanded
// ....
Try not to use expanded on growing items. If you want to cover a percentage/fractional height wrap the height with a fixed height or the full height with a container that includes box contstains, then proceed to have expanded or fixed height children. also helpful is the FracionalBox
In the example you showed there is no need for expanded, the children inside will give a content height and the SingleChildScrollView will automaticly handle scrolling based on children.
Widget build(BuildContext context) {
return ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget child, MainModel model) {
return Scaffold(
appBar: AppBar(title: Text('Order Details'), actions: <Widget>[
IconButton(
onPressed: () {
model.addNewOrder();
},
icon: Icon(Icons.add),
),
BadgeIconButton(
itemCount: model.ordersCount,
badgeColor: Color.fromRGBO(37, 134, 16, 1.0),
badgeTextColor: Colors.white,
icon: Icon(
Icons.shopping_cart,
size: 30.0,
),
onPressed: () {}),
]),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Column(children: [
_buildItemsTitle(),
Container(child: _buildOrderDetails(context, model)),
]),
Card(
child: Column(children: [
TextField(
decoration: InputDecoration(labelText: 'Offer Code'),
),
RaisedButton(
onPressed: () {},
child: Text('Apply'),
)
]),
),
Card(
child: _orderAmount(context, model),
),
RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () {},
child: Text('Checkout',
style: TextStyle(fontSize: 20.0, color: Colors.white)),
),
],
),
),
);
});
}