I want to have a list of items from my firestore, which I want to display and the user can dismiss them. (Im doing this with FirebaseApi().getSwiperData(fooNotifier)
which is giving me a copy of the data I want) If the list is empty I want to show a message.
When I'm trying to implement it without setstate
im getting the following range error:
════════ Exception caught by widgets library ═══════════════════════════════════
The following RangeError was thrown building:
RangeError (index): Invalid value: Not in inclusive range 0..2: 3
In my opinion there is no need for setstate
since im working with a Consumer
, but something doesnt work here and I really dont have an idea anymore.
Using setstate
everything works fine, but I dont want the whole widget to rebuild.
My code:
class _SwipeScreenState extends State<SwipeScreen> {
Future fooFuture;
@override
void initState() {
// TODO: implement initState
super.initState();
final fooNotifier = Provider.of<FooNotifier>(context, listen: false);
fooFuture = FirebaseApi().getSwiperData(fooNotifier);
}
@override
Widget build(BuildContext context) {
print('rebuild swipescreen');
return Stack(
children: [
Consumer<FooNotifier>(builder: (__, consumerValues, _) {
return FutureBuilder(
future: fooFuture,
// ignore: missing_return
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
break;
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
break;
case ConnectionState.done:
return consumerValues.swiperList.length != 0
? ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: consumerValues.swiperList.length ?? 0,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
resizeDuration: Duration(milliseconds: 1500),
onDismissed: (DismissDirection direction) {
//setState(() {
//Doesnt work here like expected
consumerValues.swiperList.removeAt(index);
print(consumerValues.swiperList);
// });
},
secondaryBackground: Container(
child: Center(
child: Text(
'geliked',
style: TextStyle(color: Colors.black),
),
),
color: Colors.lightGreenAccent,
),
background: Container(
child: Center(
child: Text(
'Nicht interessant',
style: TextStyle(color: Colors.black),
),
),
color: Colors.redAccent),
child: SwipeCard(
cardWidth: MediaQuery.of(context).size.width * 1,
cardHeight:
MediaQuery.of(context).size.height * 1,
foo2Name:
consumerValues.swiperList[index].foo2Name,
fooName:
consumerValues.swiperList[index].fooName,
imageUrl:
consumerValues.swiperList[index].imageUrl,
),
key: UniqueKey(),
direction: DismissDirection.horizontal,
);
},
)
: SwipeNoItems(); // Showing up if the list is empty
break;
default:
}
},
);
}),
],
);
Im proud to tell you that I fixed the problem. Im still pretty new to flutter and I can imagine that this also could be a common mistake for rookies.
As you can see in my code im working with the FutureBuilder
which is basically nothing else than a ListView.Builder
with async operations and State Management.
So when I receive my data, I'm showing them to the users. Because I'm working with Consumers
from the provider package which does listen to any state changes (Thats also why I dont need a SetState
here) Im receiving any kind of changes.
Now instead of removing my index with consumerValues.swiperList.removeAt(index);
which doesnt' communicate my changes
I created a function in my notifier class:
void removeSwipeItems(idx){
_swiperList.removeAt(idx);
notifyListeners();
}
and called the function instead, which does communicate my changes
.
consumerValues.removeSwipeItems(index);