0

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(),
                    ),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
  }
}
Hugo
  • 5
  • 1
  • Can someone please help? I know the Ternary Operator in the CircleAvatar is working correctly if I just pass in a random number. I just don't seem to get the variable of the _activePage correctly in there. Thank you so much – Hugo Jun 01 '23 at 23:57

0 Answers0