Problem is : When i click one of my CharBarButtons widget, all the other CharBarButtons are also rebuilt is there a way to avoid that and do the rebuilds individually while using StateNotifier holding List(integers are positions of buttons)
CharBarButtons : (Here i am changing the decoration of CharBarButtons according to the isTapped's boolean value)
class CharBarButtons extends HookWidget {
CharBarButtons({required this.index});
final int index;
@override
Widget build(BuildContext context) {
final isTapped = useProvider(IndexStackProvider).contains(index);
final _randomBar = useProvider(randomBarProvider);
final usableWidth = MediaQuery.of(context).size.width -
(MediaQuery.of(context).padding.left +
MediaQuery.of(context).padding.right);
final usableHeight = MediaQuery.of(context).size.height -
(MediaQuery.of(context).padding.bottom +
MediaQuery.of(context).padding.top);
return InkWell(
onTap: () {
if (isTapped == false) {
context.read(IndexStackProvider.notifier).append(index);
}
},
child: AnimatedContainer(
curve: Curves.easeOutExpo,
duration: Duration(milliseconds: 125),
child: Center(
child: Center(
child: Opacity(
opacity: isTapped == false ? 1 : 0.5,
child: Text('${_randomBar[index]}',
style: TextStyle(
color: Colors.black87,
fontWeight: FontWeight.bold,
fontSize: usableHeight * 0.03)),
))),
width: usableWidth * 0.12,
height: usableWidth * 0.12,
decoration: isTapped == false
? BoxDecoration(
color: const Color.fromRGBO(255, 227, 212, 1),
border: Border.all(
color: Colors.black.withOpacity(0.6), width: 2),
borderRadius: BorderRadius.circular(usableWidth * 0.02),
shape: BoxShape.rectangle,
)
: BoxDecoration(
color: Color.fromRGBO(199, 177, 165, 1),
border: Border.all(
color: Colors.black.withOpacity(0.3), width: 2),
borderRadius: BorderRadius.circular(usableWidth * 0.02),
shape: BoxShape.rectangle,
)));
}
}
Ancestor of CharBarButtons : CharBar widget is a simple widget , decides how many CharBarButtons should be created.
class CharBar extends HookWidget {
const CharBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final usableWidth = MediaQuery.of(context).size.width -
(MediaQuery.of(context).padding.left +
MediaQuery.of(context).padding.right);
final usableHeight = MediaQuery.of(context).size.height -
(MediaQuery.of(context).padding.bottom +
MediaQuery.of(context).padding.top);
final _randomChars = useProvider(randomBarProvider);
return Container(
height: usableWidth * 0.24,
width: usableWidth,
child: _randomChars.length <= 6
? Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
for (var i = 0; i < _randomChars.length; i++)
CharBarButtons(index: i)
])
: Column(children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (var i = 0; i < _randomChars.length ~/ 2; i++)
CharBarButtons(index: i)
],
),
SizedBox(height: usableHeight * 0.05),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (var i = _randomChars.length ~/ 2;
i < _randomChars.length;
i++)
CharBarButtons(index: i)
],
)
]),
);
}
}
Here is the StateNotifier :
class IndexStackState extends StateNotifier<List<int>> {
IndexStackState() : super([]);
void append(int index) {
state = [...state, index];
}
void delete() {
state = [...state.sublist(0, state.length - 1)];
}
void reset() {
state = [];
}
}
Here is the provider :
final IndexStackProvider =
StateNotifierProvider.autoDispose<IndexStackState, List<int>>(
(ref) => IndexStackState());
Note : CharBar (ancestor) doesn't have any unnecesary rebuilds , or another ancestor. Only the CharBarButtons are having unnecessary rebuilds.
Note 2 : I know that contains() method is also expensive but i limited the list to max 12 integer elements . So that i think it shouldn't be that much problem.
Note 3 : Problem is causing because of this line of code(first segment of code) and it rebuilds all the CharBarButtons when state is updated, i cannot listen in a index-wise manner.I am listening whole List here.
final isTapped = useProvider(IndexStackProvider).contains(index);
Note 4 : Actual problem is that, can we limit the rebuilds into a index-wise manner rather than listening whole list state