I want to use refresh indication in flutter futurebuilder. I looked for the solutuion but but not worked in my case.
I have provided my code below.
I found a solution where they suggested to use the stack but that solutiion not worked either.
column(children:[
...
const Heading("New Workers !"),
FutureBuilder(
future: SupervisorServices.getWorkersList(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
var data = snapshot.data;
if (snapshot.hasData) {
return RefreshIndicator(
onRefresh: () {
return SupervisorServices.getWorkersList();
},
child: ListView.builder(
itemCount: data.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
leading: const SizedBox(
height: double.infinity,
child: Icon(
FeatherIcons.user,
),
),
//...
),
),
);
},
),
);
}
...//rest code
},
),
...
Try add async
onRefresh: () async{
return SupervisorServices.getWorkersList();
},
Related
I want to refresh future builder data when I click on the button.
What can I do to add this functionality to my app?
I want to click on the categories and want to display the data related to the categories I clicked on.
I tried it with stream builder but it did not work. if you know how to make it work with future builders or stream builders then please provide so solution to it.
SizedBox(
height: 60,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (BuildContext context, index) {
return Center(
child: InkWell(
onTap: () {
() {};
setState(() {});
},
child: Container(
// ...rest code...
child: Text(
categories[index]['category_name'].toString(),
style: const TextStyle(color: Colors.white),
),
),
),
),
);
},
),
),
FutureBuilder(
future: getProductsByCategory(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var data = snapshot.data;
return GridView.builder(
...rest code
);
} else {
return GridView.builder(
itemCount: 7,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate:
... rest code
},
);
}
},
),
When you click on categories then save a value in global variable like-
String categoryName = "your_category_name";
then while calling the list of data set condition like -
if(categoryName.compareTo("your_listData_category")==0){
//showListData in gridView
}
SizedBox(
height: 60,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: categories.length,
itemBuilder: (BuildContext context, index) {
return Center(
child: InkWell(
onTap: () {
//Call this when Clicked Store in one List And Display Direct
List data = await getProductsByCategory()
},
child: Container(
// ...rest code...
child: Text(
categories[index]['category_name'].toString(),
style: const TextStyle(color: Colors.white),
),
),
),
),
);
},
),
),
//Use Direct Gridview
GridView.builder(
...rest code
)
After complete Api Call change state
GridView.builder you can use to show Progress
List == null ? ProgressBar : Restcode
I try to create a scrollable ListView, but for somes reasons it's not working.
My goal: create a ListView connected to Firebase. My ListView gather well datas, but scoll is impossible.
The body of my Scaffold:
body: const SingleChildScrollView(
child: RecipesInformations(),
),
My widget:
#override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _recipesStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Chargement recettes");
}
return ListView(
shrinkWrap: true,
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
List tags = List.from(document["tags"]);
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: const Color(0xFF011200)),
borderRadius: const BorderRadius.all(Radius.circular(8))),
margin: const EdgeInsets.only(
bottom: 32, left: 16, right: 16, top: 8),
padding: const EdgeInsets.all(32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data["title"],
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
style: Theme.of(context).textTheme.headline1,
)
],
),
],
));
}).toList(),
);
},
);
}
Let me know if you need more informations.
Removing SingleChildScrollView might help.
Use ListView.builder to simplify things and remove unnecessary nested scrollviews. Something like this could work:
body: RecipesInformations(),
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _recipesStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
...
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index) {
final document = snapshot.data!.docs[index];
return Container(
...
);
},
)
...
You'd need to use FutureBuilder instead of StreamBuilder.
From the docs, the StreamBuilder is a Widget that builds itself based on the latest snapshot of interaction with a Stream. So, only the last item is going to show up on the screen.
Instead, transform the stream to a List with the toList() method and use it on the FutureBuilder.future property like so:
...
return FutureBuilder<List<QuerySnapshot>>(
future: _recipesStream.toList(),
builder: (BuildContext context, snapshot) {
...
snapshot.data now is a List of QuerySnapshot. So, it's going to be a bit different to iterate over it:
...
return ListView(
shrinkWrap: true,
children: snapshot.data!.map((query) {
Map<String, dynamic> data = query.docs.first;
...
The result is going to be something like this:
In you ListViewconstructor, set primary: false since you are nesting it inside of a SingleChildScrollView.
I am trying to make a list of medicines in my mobile app. My data is in a local json file.
{
"BARKOD": 8699755640016,
"ATC KODU": "A01AA",
"ATC ADI": "Caries prophylactic agents",
"REFERANS \nE�DE�ER": "E�DE�ER",
"ESDEGERI": 2,
"ILAC ADI": "SENSORAL 250 ML SOLUSYON",
"ETKIN MADDE": "POTASYUM NITRAT + SODYUM KLORUR",
"FIRMA ADI": "DENTORAL MEDIFARMA",
"BIRIM MIKTAR": "",
"BIRIM CINSI": "",
"AMBALAJ MIKTARI": 250,
"RE�ETE": "NORMAL RE�ETE",
"KDV DAHIL PERAKENDE SATIS TL FIYATI \n1 ? =2,1166 TL": "5,69"
},
one of them is like that.
I am trying to make all of these data to appear when I click on a button. My code is like below.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:medicine_reminder/src/ui/homepage/homepage.dart';
class JsonPage extends StatefulWidget {
#override
_JsonPageState createState() => _JsonPageState();
}
class _JsonPageState extends State<JsonPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Medicine List"),
centerTitle: true,
),
body: Center(
child: FutureBuilder(
builder: (context, snapshot) {
var showData = json.decode(snapshot.data.toString());
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(
isThreeLine: true,
title: Text(showData[index]['ILAC ADI']),
subtitle: Text(showData[index]['ETKIN MADDE']),
);
},
itemCount: showData.length,
);
},
future:
DefaultAssetBundle.of(context).loadString("assets/csvjson.json"),
),
),
floatingActionButton: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 1),
child: Align(
heightFactor: 12.9,
alignment: Alignment.topLeft,
child: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
));
},
child: Icon(Icons.arrow_back),
),
),
),
],
),
);
}
}
but I can not get all the fields, I am only able to get just 2 fields 'ILAC ADI' AND 'ETKIN MADDE'.
How can I solve this?
The most efficient way to dealing with json data and rendering them is by creating models. If you are new to this QuickType can help you out with this.
Paste your json and you will get the code for the model. Next u can instantiate the model with your json data and use ListView.builder to iterate through your model and render the data.
Retroportal studio has a good video explaining this concept, take a look. I'm sure it will help you out.
Only 'ILAC ADI' and 'ETKIN MADDE' is showing on the screen because you are giving only those values in the ListTile.
Instead of a ListTile you can use a Column to show all the data.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:medicine_reminder/src/ui/homepage/homepage.dart';
class JsonPage extends StatefulWidget {
#override
_JsonPageState createState() => _JsonPageState();
}
class _JsonPageState extends State<JsonPage> {
// This List stores all the keys in the JSON
final List<String> jsonKeyList = [
'BARKOD',
'ATC KODU',
'ATC ADI',
'REFERANS \nE�DE�ER',
'ESDEGERI',
'ILAC ADI',
'ETKIN MADDE',
'FIRMA ADI',
'BIRIM MIKTAR',
'BIRIM CINSI',
'AMBALAJ MIKTARI',
'RE�ETE',
'KDV DAHIL PERAKENDE SATIS TL FIYATI \n1 ? =2,1166 TL',
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Medicine List"),
centerTitle: true,
),
body: Center(
child: FutureBuilder(
builder: (context, snapshot) {
var showData = json.decode(snapshot.data);
print(showData.toString());
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
// Used column to show all the values in the JSON
return Column(
children: jsonKeyList.map((key) {
return Text(showData[index][key].toString());
}).toList(),
);
},
itemCount: showData.length,
);
},
future:
DefaultAssetBundle.of(context).loadString("assets/csvjson.json"),
),
),
floatingActionButton: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: 1),
child: Align(
heightFactor: 12.9,
alignment: Alignment.topLeft,
child: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
));
},
child: Icon(Icons.arrow_back),
),
),
),
],
),
);
}
}
If you have any doubt comment it.
As I mentioned at the title, I got this error:
Exception caught by widgets library
Closure call with mismatched arguments: function '[]'
Receiver: Closure: () => Map<String, dynamic> from Function 'data':.
Tried calling: []("imageURL")
Found: []() => Map<String, dynamic>
I have been trying to use it to get data from firestore and show it on my app page. But I can't get the data from collection, especially for images. I referenced this tutorial from youtube. Even though I've done everything same but I couldn't handle it. Maybe bc of version. I'd be glad if you help me.
class _HomeState extends State<Home> {
PostService postService = new PostService();
Stream postStream;
//Stream postsStream;
Widget postsList() {
return SingleChildScrollView(
child: postStream != null
? Column(
children: <Widget>[
StreamBuilder(
//stream: postStream,
stream: postStream,
builder: (context, snapshot)
{
if(snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal:16.0),
itemCount: snapshot.data.docs.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return PostTile(
imgUrl: snapshot.data.docs[index].data['imageURL'],
title: snapshot.data.docs[index].data['postTitle'],
desc: snapshot.data.docs[index].data['postDesc'],
city: snapshot.data.docs[index].data['cityName'],
);
});
}),
],
): Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}
#override
void initState() {
postService.getPostData().then((result) {
setState(() {
postStream = result;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Ana Sayfa'),
backgroundColor: Colors.amber,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.group_rounded),
label: Text(''),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => KullaniciSayfasi()));
},
),
],
),
body: postsList(),
floatingActionButton: Container(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: () {
//Ekleme butonuna basıldığında
Navigator.push(context,
MaterialPageRoute(builder: (context) => CreatePost()));
},
child: Icon(Icons.add),
)
],
),
),
);
}
}
Code for post service
import 'package:cloud_firestore/cloud_firestore.dart';
class PostService{
Future<void> addData(postData) async{
FirebaseFirestore.instance.collection("posts").add(postData).catchError((e){
print(e);
});
}
getPostData() async{
return await FirebaseFirestore.instance.collection("posts").snapshots();
}
}
There was a breaking change on firebase plugins and many things have changed. E.g i see you're doing snapshot.data.docs[index].data['imageURL'] this has been changed to snapshot.data.docs[index].data()['imageURL']. Kindly check the docs for the updated API refrences
I did an app and I have a problem, I runned the app on ios and android but one screen is not like I want, all my child in SizedBox are not full displayed (only on IOS), I think it is a problem with Sizedbox in IOS but I have no Idea how to resolve it.
I try to use other widget but no one works.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: StreamBuilder(
stream: Firestore.instance
.collection('rooms')
.document(pincode)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
int result =
snapshot.data['Votes'][0] - snapshot.data['Votes'][1];
if (result <= 0)
perdantID = snapshot.data['Nominés'][1];
else
perdantID = snapshot.data['Nominés'][0];
leperdant = perdantID;
if (snapshot.data['nb screen'] == 2 && gotdata == 0) {
gotdata++;
gonext(context, perdantID);
}
return Center(
child: FutureBuilder(
future: Firestore.instance
.collection('rooms')
.document(pincode)
.collection('users')
.document(perdantID)
.get(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var prenomperdant = snapshot.data['prénom'];
return Center(
child: Column(
children: <Widget>[
SizedBox(height: 30),
Text('$prenomperdant',
style: TextStyle(fontSize: 50)),
Padding(
padding: const EdgeInsets.fromLTRB(80, 0, 0, 0),
child: Text(' $subquestion',
style: TextStyle(fontSize: 35)),
),
StreamBuilder(
stream: Firestore.instance
.collection('rooms')
.document(pincode)
.collection('users')
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
return Column(
children: <Widget>[
SizedBox(
height: 140,
child: GridView.count(
crossAxisCount: 2,
children: snapshot.data.documents.map(
(DocumentSnapshot document) {
if (document['id'] == nomines[0] ||
document['id'] == nomines[1])
return Container(
child: OvalPic(
document['photo'],
document['couleur']),
);
else
return null;
}).toList()
..removeWhere((el) => el == null)),
),
SizedBox(
height: 190,
child: GridView.count(
crossAxisCount: 2,
children: <Widget>[
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
itemCount: nbvotes[0],
reverse: true,
itemBuilder:
(BuildContext context,
int index) {
return Align(
alignment: Alignment.center,
heightFactor: 0.94,
child: Image(
image: AssetImage(
'assets/images/results/green.png'),
));
},
),
ListView.builder(
physics:
NeverScrollableScrollPhysics(),
itemCount: nbvotes[1],
reverse: true,
itemBuilder:
(BuildContext context,
int index) {
return Align(
alignment: Alignment.center,
heightFactor: 0.94,
child: Image(
image: AssetImage(
'assets/images/results/green.png'),
));
},
),
],
)),
],
);
} else
return CircularProgressIndicator();
},
),
(perdantID == nameid)
? Column(
children: <Widget>[
rbutton(mygreen, 'PASSER AU DEFI', context,
perdantID, ledefi),
SizedBox(height: 5),
Text('OU'),
SizedBox(height: 5),
rbutton(mypink, 'BOIRE', context, perdantID,
legage),
],
)
: SizedBox(height: 1)
],
));
} else
return Center(child: CircularProgressIndicator());
},
),
);
} else
return Center(child: CircularProgressIndicator());
},
));
}
}
Try to use
ConstrainedBox(
constraints: const BoxConstraints(minHeight: 140),
child:GridView....,
)
instead of
SizedBox(
height: 190,
child: GridView...
)