Flutter : RefreshIndicator with ListView Scroll - flutter

i have ListView. and listview have many item. Scroll through the screen.(vertical)
and if scroll position is Top, i want to RefreshIndicator work.
i don't know what i have to do..
now, only worked listview scroll. but when scroll position is Top, not work RefreshIndicator..
this is my code..
#override
Widget build(BuildContext context) {
return FutureBuilder<List<BoadModel>>(
future: getData(),
builder: (context, snapshot) {
List<BoadModel> dataList = snapshot.data ?? [];
if (snapshot.hasError) print(snapshot.error);
return RefreshIndicator(
onRefresh: () async {
setState(() {});
},
child: SingleChildScrollView(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Opacity(
opacity: 0.0,
child: ElevatedButton(
onPressed: () {}, child: Text("button"))),
Text(getCategoryName(widget.categoryPage)),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WriteBoadPage(
category: widget.categoryPage,
),
),
);
},
child: Text("글쓰기"))
],
),
snapshot.hasData
? Column(
children: [
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: dataList.length,
itemBuilder: (BuildContext context, int index) {
return ListViewItem(
title: dataList[index].title,
nickname: dataList[index].nickname,
time: dataList[index].time,
view: dataList[index].view,
commentCount: dataList[index].comment);
},
),
Row(
children: [Text("dafs")],
)
],
)
: Center(
child: CircularProgressIndicator(),
)
],
),
),
);
},
);
}

I found a solution but there is another problem.
The problem is that I have SingleChildScrollView already in parent widget like shown below:
return SingleChildScrollView( //have SingleChildScrollView already
child: Column(
children: [
RefreshIndicator(
child: SingleChildScrollView(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListViewItem();
},
),
),
onRefresh: () async {}),
],
),
);
So I did it like shown below:
#override
Widget build(BuildContext context) {
return RefreshIndicator(
child: SingleChildScrollView(
child: Column(
children: [
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListViewItem();
},
),
],
),
),
onRefresh: () async {},
);

Related

RenderShrinkWrappingViewport does not support returning intrinsic dimensions

I want a text button when on click shows a simpleDialog vith a listView.builder but I don't know how to code it. I always have an error.
Can you help me?
Here is my code:
TextButton(
child: const Text('Selet instruments needed'),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) => SimpleDialog(
contentPadding: const EdgeInsets.all(15),
title: const Text('Select instruments needed'),
children: [
ListView.builder(
shrinkWrap: true,
itemCount: 2,
itemBuilder: ((context, index) {
return ListTile(
title: instrumentType[index]['name'],
onTap: () {});
}))
]));
})
You can wrap your ListView with SizedBox widget and using LayoutBuilder help to get the constraints
TextButton(
child: const Text('Selet instruments needed'),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) => LayoutBuilder(
builder: (context, constraints) => SimpleDialog(
contentPadding: const EdgeInsets.all(15),
title: const Text('Select instruments needed'),
children: [
SizedBox(
height: constraints.maxHeight * .7, // 70% height
width: constraints.maxWidth * .9,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: 44,
itemBuilder: ((context, index) {
return ListTile(onTap: () {});
}),
),
)
],
),
),
);
})
Try below code :
void _show(BuildContext ctx) {
showDialog(
context: ctx,
builder: (_) {
return SimpleDialog(
title: const Text('The Title'),
children: [
SimpleDialogOption(
child: const Text('Option 1'),
onPressed: () {
// Do something
print('You have selected the option 1');
Navigator.of(ctx).pop();
},
),
SimpleDialogOption(
child: const Text('Option 2'),
onPressed: () {
// Do something
print('You have selected the option 2');
Navigator.of(ctx).pop();
},
)
],
);
},
);
}
Call Dialog function :
TextButton(
child: const Text('Show The Simple Dialog'),
onPressed: () => _show(context),
),

Flutter end of ListView from data in Firestore

I'd like to add some empty tiles to the bottom of my listview so that I can put "See More" button on that part. The data I'm displaying on the screen is from Firebase. This is something I learned from YouTube tutorials. This is my code.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: StreamBuilder(
stream: Collection.limit(10).snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return !snapshot.hasData
? Center(child: CircularProgressIndicator())
: ListView(
children: snapshot.data!.docs.map((document) {
return Center(
child: Card(
margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 1.0),
child: ListTile(
title: Text(document['title']),
subtitle: Text(document['body']),
onTap: () async { },
),
),
);
}).toList(),
);
},
),
);
}
Some people have already advised me to use ListView.builder, but I'm not sure how to implement it in my code. I repeatedly tried to use ListView.Builder but failed.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: StreamBuilder(
stream: Collection.limit(10).snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (_, index) => Center(
child: Column(
children: [
Card(
margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 1.0),
child: ListTile(
title: Text("some text"),
subtitle: Text("some text"),
onTap: () async {},
),
),
TextButton(onPressed: () {}, child: Text("See More"))
],
)));
},
),
);
}

FutureBuilder rebuilds because of TextField in Flutter

The problem is when I try to input some text into textfield, the keyboard shows up for a second, and then the whole FutureBuilder rebuilds immediately.
Here is my FutureBuilder
body: FutureBuilder(
future: Provider.of<Activities>(context, listen: false).fetchAndSet(),
builder: (context, snapshot) => snapshot.connectionState ==
ConnectionState.waiting
? Center(child: CircularProgressIndicator())
: Consumer<Activities>(
child: Center(
child: const Text('nothing here'),
),
builder: (context, activities, ch) => SingleChildScrollView(
child: Center(
child: Column(children: [
Container(
padding:
EdgeInsets.only(top: mediaQuery.size.height / 40),
child: Text(time, style: TextStyle(fontSize: 30)),
),
DayContainer(mediaQuery, activities),
Container(
height: 300,
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
children: <Widget>[
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: activities.activities.length,
itemBuilder: (context, index) {
return ElementPicker(
mediaQuery,
// this.callbackN,
activities.activities[index]);
})
],
),
),
),
FloatingActionButton(
onPressed: () => activities.addActivity(
'0Adding0', 'Добавить активность', 0.0, 0.0),
child: Icon(Icons.add),
)
]),
),
),
),
)
Inside of ElementPicker, there is another widget in which there is TextField
You need to initialize your futures in the initState so that whenever the widget rebuilds for any reason (in this case opening of the keyboard), you don't perform the fetchAndSet again:
void initState() {
super.initState();
fetchAndSetFuture = Provider.of<Activities>(context, listen: false).fetchAndSet();
}
...
//in build()
FutureBuilder(
future: fetchAndSetFuture,
builder: ...
);

How to add a DraggableScrollableSheet inside ListView

body: RefreshIndicator(
onRefresh: _onRefresh,
child: ListView(
children:[
Stack(
children: [
BuildMainProfile(
screenHeight: screenHeight,
screenWidth: screenWidth,
uid: widget.uid,
callBack: widget.callBack,
),
DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.blue[100],
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
);
},
)
],
),
] ),
),
The above codes give an error
These invalid constraints were provided to RenderFractionallySizedOverflowBox's layout() function by the following function, which probably computed the invalid constraints in question:
So How can we use DraggableScrollableSheet inside ListView
ListView is only used because of RefreshIndicator, it serves no other purpose. So is there an Alterntive

Display ListView items in a row

I am having a hard time figuring out how to get my FilterChips in a row.
I would like to display all FilterChips per category in a row and not in a seperated column.
Tried different approaches but non of them seems to work.
Hopefully someone can help me with this, thanks for help!
Here is my code:
Widget _buildListView(List<Category> categories) {
return Column(
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: categories.length,
itemBuilder: (context, index) {
return _buildSection(categories[index]);
},
),
),
],
);
}
Widget _buildSection(Category category) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
category.title,
style: TextStyle(fontSize: 18),
),
// How can I get my FilterChips side by side?
Row(
children: [
Flexible(
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: category.interests.length,
itemBuilder: (context, index) {
Interest interest = category.interests[index];
return FilterChip(label: Text(interest.interest), onSelected: (isSelected){
selectedInterests.add(interest.id);
});
return Text(interest.interest);
}),
),
],
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: categories,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Category> categories = snapshot.data;
return _buildListView(categories);
}
return Center(child: CircularProgressIndicator());
},
),
);
}
class StackOver extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(
top: 60,
left: 10.0,
right: 10.0,
),
child: Wrap(
children: List.generate(
10,
(index) {
return FilterChip(
label: Text('index $index'),
onSelected: (val) {},
);
},
),
),
),
);
}
}
RESULT: