I manually coded a TabPageSelector allowing users to see their progress in scrolling through the pages (from a PageView.builder). However I cannot seem to successfully pass-down the _activePage to the CircleAvatar that needs to change color. My problem seems to be at:
_onPageViewChange(int page) { setState(() { _activePage = page; }); print("Current Page: $_activePage"); }
If I don't use the setState, then I can scroll through the pages and check the _activePage when printing it. However, if I use the setState (so that the _activePage variable gets automatically updated in the CircleAvatar, I can no longer scroll through the pages. I just cannot figure out what goes wrong. Please have a look and give me some suggestions. Please see my code below:
class BookFeeder extends StatefulWidget { const BookFeeder({super.key}); static const String id = 'BookFeeder'; @override State<BookFeeder> createState() => _BookFeederState(); } class _BookFeederState extends State<BookFeeder> { //declare page controller final PageController _pageController = PageController(initialPage: 0); //Hide the AppBar and bottomNavigationBar bool _showAppBar = false; bool _showBottomBar = false; // Declare starting page int _activePage = 0; _onPageViewChange(int page) { setState(() { _activePage = page; }); print("Current Page: $_activePage"); } @override Widget build(BuildContext context) { return Scaffold( appBar: _showAppBar ? AppBar( leadingWidth: 120, backgroundColor: const Color( (0XFF293D63), ), leading: IconButton( onPressed: () { //print('Go Back Pressed'); Navigator.pop(context); }, icon: SvgPicture.asset('images/button_goback_clean_svg.svg'), ), //Add to the Appbar the favourites, quizz and settings and next page //title: Text('First Page'), centerTitle: true, actions: [ IconButton( iconSize: 45, onPressed: () { Navigator.pushNamed(context, MySettings.id); }, icon: SvgPicture.asset('images/button_settings_clean_svg.svg'), ), ], ) : null, // make the navigationbar look better bottomNavigationBar: _showBottomBar ? BottomAppBar( shape: const CircularNotchedRectangle(), color: Colors.white, elevation: 9, child: StreamBuilder( stream: FirebaseFirestore.instance //Below defines which collection to get .collection('fishingmonkey') .snapshots(), builder: (context, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( height: 70, //width: 300, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: snapshot.data!.docs.length, itemBuilder: (context, index) => Padding( padding: const EdgeInsets.fromLTRB(8, 16, 8, 16), child: InkWell( onTap: () { print("Current Page: $_activePage"); // _pageController.animateToPage(index, // duration: const Duration(milliseconds: 300), // curve: Curves.easeIn); }, child: CircleAvatar( radius: 10, backgroundColor: _activePage == index ? const Color(0XFF293D63) : Colors.blue[100], ), ), ), ), ) ], ); }, ), ) : null, body: GestureDetector( onTap: () { setState(() { _showAppBar = !_showAppBar; _showBottomBar = !_showBottomBar; }); }, child: ScrollConfiguration( behavior: ScrollConfiguration.of(context).copyWith( dragDevices: { PointerDeviceKind.touch, PointerDeviceKind.mouse, }, ), child: ScrollEdgeListener( edge: ScrollEdge.end, edgeOffset: 0, continuous: false, debounce: const Duration(milliseconds: 200), dispatch: true, listener: () { print('end reached'); Navigator.pop(context); }, child: ScrollConfiguration( behavior: ScrollConfiguration.of(context).copyWith( dragDevices: { PointerDeviceKind.touch, PointerDeviceKind.mouse, }, ), child: StreamBuilder( stream: FirebaseFirestore.instance //Below defines which collection to get .collection('fishingmonkey') .snapshots(), builder: (context, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } //below is going to create all the different Pageviews() depending on the number of 'docs' // this can be NULL (hence !) and .length provides the number return PageView.builder( onPageChanged: _onPageViewChange, controller: _pageController, itemCount: snapshot.data!.docs.length, itemBuilder: (context, index) => BookContent( //here you will request the data from 'docs' and request the whole index (starts from 0; can also do index +1) // snap: snapshot.data!.docs[index].data(), ), ); }, ), ), ), ), ), ); } }