Reputation: 1354
I'm using this beautiful Accordion package.
I have a few different situations where state changes in Accordion child widgets are causing entire Accordion widget rebuilds which in turn causes accordions to close on state change. My example below is highly simplified. The CustomRadioButton enforcedValue is the state change.
For example, a radio button is tapped, the state changes and the accordion closes. Upon reopening the accordion the state is updated.
Of course this is undesired, the entire accordion parent should not rebuild. I'm using Riverpod, the whole point of riverpod is to enact only rebuilds of child widgets that require it and not rebuild larger parents.
I have tried messing around with keys but I don't have any conclusive good changes to report along this line.
What am I doing wrong here? Is there something I can change while maintaining widget reusability as I currently have?
class Page extends ConsumerWidget {
const Page({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
// Exemplary boolean visibility values (not important for this, just showing for example)
bool one = true;
bool two = true;
bool three = true;
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
pulldownExample(context, ref, null),
Visibility(visible: one, child: pulldownExample(context, ref, 0)),
Visibility(visible: two, child: pulldownExample(context, ref, 1)),
Visibility(visible: three, child: pulldownExample(context, ref, 2)),
],
),
);
}
// FP magnitude notification pulldown
Widget pulldownExample(
BuildContext context,
WidgetRef ref,
int? index,
) {
return Accordion(
scaleWhenAnimating: false,
openAndCloseAnimation: true,
flipRightIconIfOpen: true,
disableScrolling: true,
children: [
AccordionSection(
header: Text('DYNAMIC HEADER TEXT'),
content: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CustomRadioButton(
enforcedValue: ref.watch(exampleState).valueOne, // Trouble here when this state changes
onTap: (_) => onTapLogic(),
),
const SizedBox(width: 8),
Text('ONE'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CustomRadioButton(
enforcedValue: ref.watch(exampleState).valueTwo, // Trouble here when this state changes
onTap: (_) => onTapLogic(),
),
const SizedBox(width: 8),
Text('TWO'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CustomRadioButton(
enforcedValue: ref.watch(exampleState).valueThree, // Trouble here when this state changes
onTap: (_) => onTapLogic(),
),
const SizedBox(width: 8),
Text('THREE'),
],
),
],
),
),
],
);
}
}
Upvotes: 1
Views: 818
Reputation: 4844
First, your pulldownExample
method needs to be converted into a separate ConsumerWidget
widget with the required fields. This will optimize rebuilds.
Second, you can use the Consumer
widget inside the build
method to rebuild only those parts of the tree that need to be rebuilt. Also consider using select
for the exampleState
provider.
Links:
Upvotes: 2