As per the official document StateNotifierProvider it’s working fine, but I have a scenario to pass some value at the initial stage, flow is going like this, I have a list of items, and after clicking on it, it will be redirected to the details screen, when user swipe left or right with PageView.builder title hast be updated, it’s working fine when user swipe the page, but when user clicks on the 3rd item from the list I want to show title with the selected item, so I want to pass initial position to StateNotifierProvider
class ControllerPositionNotifier extends StateNotifier {
final currentPosition;
ControllerPositionNotifier(this.currentPosition) : super(currentPosition);
int position(int position) {
return state = position;
}
}
I want to pass a my value when I enter into widget ControllerPositionNotifier(MY_ARG)
final controllerPositionNotifier = StateNotifierProvider<ControllerPositionNotifier, int>((ref) {
return ControllerPositionNotifier(0);
});
View pager screen
class SongWidget extends ConsumerStatefulWidget {
final List<dynamic>? resultData;
final int position;
const SongWidget({Key? key, required this.resultData, required this.position})
: super(key: key);
@override
_SongWidgetState createState() => _SongWidgetState();
}
class _SongWidgetState extends ConsumerState<SongWidget> {
@override
Widget build(BuildContext context) {
final songs = widget.resultData?.map((e) => Song.fromJson(e)).toList() ??
List<Song>.empty();
int position = ref.watch(controllerPositionNotifier);
// HERE I WANT TO PASS ON MY ARGUMENT widget.position
final PageController controller =
PageController(initialPage: widget.position);
print('_SongWidgetState');
return Scaffold(
appBar: AppBar(
title: Text(songs[position].sTitle ?? '--'),
),
body: PageView.builder(
controller: controller,
itemCount: songs.length,
onPageChanged: (index) {
print('position: $index');
ref.watch(controllerPositionNotifier.notifier).position(index);
},
itemBuilder: (context, index) {
return SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Text(
songs[index].sSong ?? '--',
),
)
],
),
);
},
),
);
}
}
This line hast be updated the initial stage
appBar: AppBar(
title: Text(songs[position].sTitle ?? '--'),
)
After swipe updating successfully
ref.watch(controllerPositionNotifier.notifier).position(index);
But I would like to pass some value at the initial stage
2
Answers
To provide initial value when I get into the widget, I did update the provider before entering into the widget
I did update the value, inside onTap() before moving to the SongWidget
onTap() - method
Use the new api from riverpod 2.0 to pass the parameter:
In the widget it will look like this:
Note: use
ref.read
in the callbacks