I have a list of all deals _deals
and a list of selected deals _selectedDeals
. Deals can be added to or removed from the list _selectedDeals
from another class. So if a new deal is added/removed, I want to rebuild this DealsWidget
so the newly added/removed deal is properly reflected in UI.
And I'm using BookButton
stateful widget, to show if a deal is selected or not. When isBooked
is true, it means that the deal is selected.
I planned to achieve this behavior by calling the refresh()
function of DealsWidget
after data is added/removed from that other class so it would rebuild everything and my UI is consistent with data, but nothing happened.
What I've found out is that rebuilding won't recreate BookButton
widgets again. Their constructors are not called again. And that is why my updated value is not getting entertained, because I'm passing them in constructor of BookButton
.
Can anyone explain why is this happening and how can I properly show which deals are selected and which are not?
DealsWidget
class DealsWidget extends StatefulWidget {
final List<Deal> _deals;
final List<Deal> _selectedDeals;
final DealSelectionListener _dealSelectionListener;
DealsWidget(
Key dealsKey,
this._deals,
this._selectedDeals,
this._dealSelectionListener,
) : super(key: dealsKey);
@override
DealsWidgetState createState() => DealsWidgetState();
}
class DealsWidgetState extends State<DealsWidget> {
@override
Widget build(BuildContext context) {
final totalDeals = widget._deals.length;
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: totalDeals,
shrinkWrap: true,
itemBuilder: (context, index) {
final deal = widget._deals[index];
final isSelected = widget._selectedDeals.contains(deal);
return Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: BookButton(
isSelected,
(isBooked) {
if (isBooked) {
widget._dealSelectionListener._onSelected(deal);
} else {
widget._dealSelectionListener._onDeselected(deal);
}
}
),
);
}
);
}
void refresh() {
print('Refreshing deals');
setState(() {
});
}
}
BookButton
class BookButton extends StatefulWidget {
final bool isBooked;
final OnBookChangedListener listener;
BookButton(this.isBooked, this.listener);
@override
BookButtonClass createState() => BookButtonClass(isBooked);
}
class BookButtonClass extends State<BookButton> {
bool isBooked;
BookButtonClass(this.isBooked);
void check(bool check) {
setState(() {
isBooked = check;
widget.listener.call(isBooked);
});
}
@override
Widget build(BuildContext context) {
return FlatButton(
onPressed: (){
setState(() {
isBooked = !isBooked;
widget.listener.call(isBooked);
});
},
child: Text(
isBooked ? AppStrings.unbook.toUpperCase() : AppStrings.book.toUpperCase(),
style: TextStyle(
color: isBooked ? AppColors.accentColor : Colors.white,
fontSize: 12,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: BorderSide(
color: AppColors.accentColor,
width: isBooked ? 1 : 0,
)
),
color: isBooked ? Colors.transparent : AppColors.accentColor,
);
}
}