Could not find the correct Provider - Flutter - flutter

#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Stack(
children: <Widget>[
DefaultTabController(
length: 5,
child: ChangeNotifierProvider(
builder: (context) => MySchedule(),
child: (
Scaffold(
appBar: AppBar(
actions: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GestureDetector(
onTap: () async{
await Navigator.of(context).push(
MaterialPageRoute(builder: (context){
return InApp();
})
);
final MySchedule schedules = Provider.of<MySchedule>(context);
schedules.numberOfCoins = 10;
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: <Widget>[
Consumer<MySchedule>(
builder: (context, coin, _) =>
buildCoinBar(coin),
),
SizedBox(
width: 2,
),
Stack(
children: <Widget>[
Image.asset('assets/coin2.png',
height: 22, width: 22,),
],
),
],
),
),
),
),
Image.asset('assets/LOGO.png'),
Consumer<MySchedule>(
builder: (context, userdata, _) =>
topRightElement(userdata, context),
),
],
),
)
],
automaticallyImplyLeading: false,
bottom: TabBar(
labelStyle: TextStyle(fontSize: 8),
tabs: [
Consumer<MySchedule>(
builder: (context, schedule, _) =>
buildNewCardNotification(schedule),
),
Tab(icon: Icon(Icons.star), text: 'Csapatom' ,),
Tab(icon: Icon(Icons.verified_user), text: 'Forduló',),
Tab(icon: Icon(Icons.stars), text: 'Kártyáim',),
Tab(icon: Icon(Icons.account_balance), text: 'Ligák',),
],
),
),
body: TabBarView(
children: [
Office(),
MyTeam(),
MatchListView(),
MyCardView(),
ChampionshipView2(),
],
),
)
),
),
),
Visibility(
visible: msgVisible,
child: SafeArea(
child: GestureDetector(
onTap: (){
setState(() {
msgVisible = false;
});
},
child: Padding(
padding: const EdgeInsets.all(2.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(0.0),
child: Card(
shape: RoundedRectangleBorder(
side: new BorderSide(color: Colors.lightGreenAccent, width: 2.0),
borderRadius: BorderRadius.circular(16.0)),
elevation: 8,
color: Colors.black87,
child: Container(
height: 64,
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: Image.asset('assets/LOGO.png', height:44),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(title, style: TextStyle(
fontSize: 16,
color: Colors.lightGreenAccent
),),
Text(body,
overflow: TextOverflow.ellipsis)
],
),
],
),
),
),
),
),
),
),
)
],
),
);
}
I try to modify the numberOfCoins variable, when I pop the InApp() class.
But I have the following error:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: Error: Could
not find the correct Provider above this FantasyNbi Widget
To fix, please:
Ensure the Provider is an ancestor to this FantasyNbi
Widget * Provide types to Provider * Provide types to
Consumer * Provide types to Provider.of()
Always use package imports. Ex: import 'package:my_app/my_code.dart'; * Ensure the correct context` is
being used.

You need a builder bridge between ChangeNotifierProvider and Scaffold.
Provider package already has it's own builder called Consumer, you can use it like:
ChangeNotifierProvider<MySchedule>(
create: (context) => MySchedule(),
child: Consumer<MySchedule>(
builder: (context, provider, child) => Scaffold(....,
Check this link: https://pub.dev/packages/provider#reading-a-value
edit: builder is now create.

According to the latest version of the Provider package, the builder() method of ChangeNotifierProvider was changed to create().
So editing Esen Mehmet's version, this will work instead:
ChangeNotifierProvider(
create: (context) => MySchedule(), //change builder to create
child: Consumer<MySchedule>(
builder: (context, provider, child) => Scaffold(....,

You can use provider as Below,
class HomeApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return HomeAppState();
}
}
class HomeAppState extends State<HomeApp> {
final _user = UserModel();
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<LoginNotifier>(create: (BuildContext context) {
return LoginNotifier();
}),
ChangeNotifierProvider<UserModel>.value(value: _user),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: Provider.of<ThemeModel>(context).currentTheme,
home: HomeScreen(),
));
}
}

Related

How to stack two bottom sheet in flutter?

I want to stack two bottom sheet each other in flutter as show in photo. The upper one is shown when in error state. In photo, it build with alert dialog. I want is with bottom sheet. How can I get it?
Edit:
Here is my code that I want to do. Lower bottom sheet is with pin field, autoComplete. autoComplete trigger StreamController, and then streamBuilder watch Error state and show dialog.
confirmPasswordModalBottomSheet(
BiometricAuthRegisterBloc biometricAuthRegBloc) {
showMaterialModalBottomSheet(
context: context,
builder: (BuildContext context) {
return StreamBuilder(
stream: biometricAuthRegBloc.biometricAuthRegisterStream,
builder: (context,AsyncSnapshot<ResponseObject>biometricAuthRegSnapShot) {
if (biometricAuthRegSnapShot.hasData) {
if (biometricAuthRegSnapShot.data!.messageState ==
MessageState.requestError) {
showModalBottomSheet(context: context, builder:
(BuildContext context){
return Container(
width: 200,height: 200,
child: Center(child: Text('Helllllllllo'),),);
});
}
}
return SizedBox(
width: 100,
height: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: margin30,
),
Text(CURRENT_PIN_TITLE),
SizedBox(
height: margin30,
),
Padding(
padding: const EdgeInsets.only(
left: margin60, right: margin60),
child: PinCodeField(
pinLength: 6,
onChange: () {},
onComplete: (value) {
biometricAuthRegBloc.biometricAuthRegister(
biometricType:_biometricAuthTypeForApi,
password: value);
},
),
),
SizedBox(
height: margin30,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal:
margin80),
child: AppButton(
onClick: () {},
label: CANCEL_BTN_LABEL,
),
),
Container(
padding: const EdgeInsets.all(8.0),
margin:
EdgeInsets.symmetric(vertical: 8.0,
horizontal: 30),
decoration: BoxDecoration(
color: Colors.grey,
border: Border.all(color: Colors.black),
),
child: const Text(
FINGER_PRINT_DIALOG,
textAlign: TextAlign.center,
),
)
],
),
);
});
},
);
}
When I do like that above, I get setState() or markNeedsBuild() called during build. Error and why? Sorry for my previous incomplete question.
I am bit confused with your question but stacking two bottomsheet is just easy. You just need to call the showModalBottomSheet whenever you want it shown to user. You can check out the following implementation:
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ElevatedButton(
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 500,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet 1'),
ElevatedButton(
child: const Text('Show second modal 2'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.redAccent,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet 2'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
),
],
),
),
);
},
);
},
),
],
),
),
);
},
);
},
child: Text('Show bottom sheet 1'),
),
);
}
}
I have solution. All I need to do is, need to add WidgetBinding.insatance.addPostFrameCallback((timeStamp){showModalBottomSheet()}); in the StreamBuilder return.

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.

Error: Could not find the correct Provider<CartList> above this Consumer<CartList> Widget in flutter

This is a part of code for run app:
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => _number != null?ChangeNotifierProvider(
create: (context)=>CartList(),
child: HomeScreenDemo(),
):Login())));
I've also tried using MultiProvider instead of ChangeNotifierProvider but it didn't work.
This is the part of Code for home Screen:
Widget build(BuildContext context) {
return Consumer<CartList>(
builder: (context,CART,child){
return Scaffold(
key: scaffoldKey,
backgroundColor: Colors.black,
)
This is how I'm Navigating to checkOut Screen:
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CartScreen(userPin: _userPin,)
));
This is the code of checkOut Screen:
Widget build(BuildContext context) {
return Builder(builder: (BuildContext context)=>Consumer<CartList>(
builder: (context,cart,child){
return Scaffold(
backgroundColor: Colors.black,
I've tried removing builder before Consumer But it didn't work.
This Is the ScreenShot of error:
Here I'm pushing the route:
showCart? Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),color: Colors.cyan,
),
child: Material(
color: Colors.transparent,
child: InkWell(
splashColor: Colors.black12,
onTap: () {
// Cart OnClick
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ChangeNotifierProvider.value(
value: Provider.of<CartList>(context, listen: false),
child: CartScreen(userPin: _userPin,)
)
));
},
child: Container(
width:MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(CART.count<=1?CART.count.toString()+" ITEM":CART.count.toString()+" ITEMS",style: TextStyle(
letterSpacing: 1.5,fontWeight: FontWeight.w400
),),
SizedBox(height: 5,),
Text(" ₹"+CART.totalPrice.toString().replaceAll(regex, "")),
],
),
SizedBox(width: 160,),
Text('Cart ',style: TextStyle( fontSize: 18,letterSpacing: .5,fontWeight: FontWeight.w400),textAlign: TextAlign.end,),
Icon(Icons.arrow_right,size: 30,),
],
),
padding: EdgeInsets.all(10),
height: 60,
),
),
),
),
),
):Container()
Check the widget tree in Android Studio or VS and you will see that when pushing a route it starts fresh with only MaterialApp (Unless you create the Provider before the MaterialApp) above so there is no CartList to consume, wrap it in a ChangeNotifierProvider.value to expose a previous created provider
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => ChangeNotifierProvider.value( //this context change its name to something else to avoid confusion
value: Provider.of<CartList>(context, listen: false),
child: CartScreen(userPin: _userPin,)
)
));

A RenderFlex overflowed by 1443 pixels on the bottom

I am trying to make it scrollable...enter image description here For some reason its not not scrolling and i tried adding singleChildScrollview still not working.... Pls look at the picture to understand better... so i posted the full code so that you guys can help me better... This was the error i got "Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size. This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView."
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:memoryblog/helper/authenticate.dart';
import 'package:memoryblog/services/auth.dart';
import 'package:memoryblog/services/database.dart';
import 'package:memoryblog/views/create_blog.dart';
class MemoryRoom extends StatefulWidget {
#override
_MemoryRoomState createState() => _MemoryRoomState();
}
class _MemoryRoomState extends State<MemoryRoom> {
AuthMethod authMethod = new AuthMethod();
DatabaseMethods databaseMethod = new DatabaseMethods();
Stream blogsStream;
Widget BlogsList(){
return Container(
child: blogsStream != null ? Column(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot){
if(snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index){
return BlogsTile(
authorName: snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description: snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
}
);
},
)
],
) : Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
)
);
}
#override
void initState() {
// TODO: implement initState
databaseMethod.getData().then((result){
setState(() {
blogsStream = result;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Text(
"Memory"
),
Text(
"Blog",
style: TextStyle(
color: Colors.blue
),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: (){
authMethod.signOut();
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => Authenticate()
));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.power_settings_new)),
)
],
),
body: BlogsList(),
floatingActionButton: Container(
padding: EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => CreateBlog()
));
},
child: Icon(Icons.add),
)
],
),
),
);
}
}
class BlogsTile extends StatelessWidget {
String imgUrl, title, description, authorName;
BlogsTile({#required this.imgUrl, #required this.title, #required this.description, #required this.authorName,});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16),
height: 170,
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: CachedNetworkImage(
imageUrl: imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
)
),
Container(
height: 170,
decoration: BoxDecoration(
color: Colors.black45.withOpacity(0.3),
borderRadius: BorderRadius.circular(6)
),
),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
SizedBox(height: 4,),
Text(
description,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
SizedBox(height: 4,),
Text(authorName)
],
),
)
],
),
);
}
}
Use ListView in place of the column. OR
Wrap Column with SingleChildScrollView
return Container(
child: blogsStream != null
? ListView(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot) {
if (snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BlogsTile(
authorName:
snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description:
snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);

Flutter sort data Firestore with Streambuilder

My goal: When the user presses the "List" button inside "_mainListItem" I want the listview to get sorted by orderBy. Aswell as updated on screen
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class mainlist extends StatefulWidget {
#override
_mainlistpage createState() => _mainlistpage();
}
class _mainlistpage extends State<mainlist> {
Widget homePage() {
return StreamBuilder(
stream: Firestore.instance.collection("Test").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading");
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_mainListItem(context, snapshot.data.documents[index]));
},
);
}
Widget _mainListItem(BuildContext context, DocumentSnapshot document) {
return Card(
color: Colors.white,
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => profile(context, document)));
},
child: Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.black12))),
child: Row(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
children: <Widget>[
Stack(
alignment: Alignment.topRight,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5),
child: ClipRRect(
borderRadius:
BorderRadius.circular(0.0),
child: FittedBox(
child: Image.asset(
"assets/Profile Picture.png",
fit: BoxFit.fill,
)),
),
),
Padding(
padding: const EdgeInsets.only(
top: 7, right: 4),
child: Text(
'Test',
style: TextStyle(fontSize: 12),
),
),
]),
Row()
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
document['name'],
),
// Text("2km"),
],
),
],
),
],
),
),
],
),
),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 5),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 10, right: 7),
child: Container(
child: Material(
borderRadius: BorderRadius.circular(5),
shadowColor: Colors.black,
elevation: 1,
child: SizedBox(
height: 28,
width: 68,
child: IconButton(
padding: EdgeInsets.only(bottom: 10),
**icon: Icon(Icons.list),
disabledColor: Colors.blue,
iconSize: 25,**
)),
),
),
),
],
),
)
],
)
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
backgroundColor: Colors.grey,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
color: Colors.red,
),
title: Text("Test"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.menu),
iconSize: 30,
color: Colors.white,
)
],
),
body: homePage(),
);
}
}
I have tried
- adding the streambuilder function into the ontapped: on the List button
- have read and watched every video there is and still can't find the solution
note: the app looks weird because I deleted unnecessary information
You can sort the list items before the snapshot method like:
.orderBy('sortField', descending: true).snapshot()
I hope this works for you.
Try mapping the values to a List<CustomObject> and using the list of objects in your list view.
i suggest you use state to determine the field how your list will be sorted by.
this is what i'd do to achieve this (continuing from the same code):
...
class _mainlistpage extends State<mainlist> {
String _orderBy = 'defaultSort'; //? HERE YOU PUT WHAT YOUR SORTING FIELD NAME IS
bool _isDescending = true; //? THIS IS WHAT WILL SET THE ORDER SORTING
Widget homePage() {
return StreamBuilder(
stream: Firestore.instance
.collection("Test")
.orderBy(_orderBy, descending: _isDescending) //? PUT THE ORDERBY QUERY HERE
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Text("Loading");
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_mainListItem(context, snapshot.data.documents[index]));
},
);
}
...
somewhere in the class, put the button or dropdown and use setState(...) to set the
states of the new variables.
NOTE: you might have to create 'indexes' in firestore. you will get errors when a new
index is required.