skip to Main Content

I want to access page view as well as the bottom navigator with the same controller so that I can have that page swipe action that page view has by default.

I wanted to link pageview screens to the bottom navigator with the controller to have a swipe page change action. Now I do have to use page view with bottom navigator, but which is linked together with the current index number due to which page swipe transitions fail to execute. now the page changes only when I click the specific page on the bottom navigator.
and i need to reduce the api calling too..
i am using AutomaticKeepAliveClientMixin as of now

Is there any other way I can get the page swipe transition to sync with the bottom navigator Which can also reduce the api calling??

Code
Scaffold part

Scaffold(
                    appBar: ToolbarNavigation(title, CustomColors.colorBlue),
                    body: PageView(
                      physics: const NeverScrollableScrollPhysics(),
                      controller: pageController,
                      onPageChanged: onPageChanged,
                      children: screens,
                    ),
                    /* Bottom Navigator */
                    bottomNavigationBar: BottomNavigationBar(
                      currentIndex: _currentIndex,
                      selectedItemColor: CustomColors.colorBlue,
                      type: BottomNavigationBarType.fixed,
                      iconSize: 30,
                      items: [
                        BottomNavigationBarItem(
                          icon: Image(
                            image: const AssetImage(Constants.Home),
                            height: 30,
                            width: 30,
                          ),
                          label: 'Home',
                          tooltip: '',
                        ),
                        BottomNavigationBarItem(
                          icon:  const AssetImage(Constants. a),
                            height: 30,
                            width: 30,
                          ),
                          label: 'A',
                          tooltip: '',
                        ),
                        BottomNavigationBarItem(
                          icon: Image(
                            image: const AssetImage(Constants. b),
                            height: 30,
                            width: 30,
                          ),
                          label: 'B',
                          tooltip: '',
                        ),
                        BottomNavigationBarItem(
                          icon: Image(
                            image: const AssetImage(Constants.c),
                            height: 30,
                            width: 30,
                          ),
                          label: 'C',
                          tooltip: '',
                        ),

                      ],
                      onTap: (index) {
                        onTabChange(index);
                      },
                    ),
                  ),
 @override
  void initState() {
    screens = [
      Home(),
      const A(),
      const B(),
      const C(),
     
    ];
    pageController = PageController(initialPage: widget.pageNumber);
    _currentIndex = widget.pageNumber;
    super.initState();
    SchedulerBinding.instance.addPostFrameCallback((_) {
   
    });
  }

OnTabChange & OnPageChange

  int _currentIndex = 0;

void onTabChange(index) {
    setState(() {
      _currentIndex = index;
    });
    pageController.jumpToPage(index);
  }

  void onPageChanged(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

3

Answers


  1. var selectedIndex = 0;
    List<Widget> tabList = [
    const YouTubeScreen(),
    Container(color: Colors.red,),
    Container(color: Colors.green,),
    ];
    
    PageController pageController = PageController();    
    
    Scaffold(
        bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Colors.white,
        currentIndex: selectedIndex,
        selectedItemColor: Colors.black,
        unselectedItemColor: Colors.grey,
        onTap: (index){
          setState(() {
            selectedIndex = index;
          });
          pageController.jumpToPage(index);
        },
        items: const [
          BottomNavigationBarItem(icon: 
      Icon(Icons.ondemand_video_sharp),label: "Youtube"),
          BottomNavigationBarItem(icon: 
      Icon(Icons.video_collection_rounded),label: "Local"),
          BottomNavigationBarItem(icon: Icon(Icons.settings),label: 
      "Setting")
        ],
      ),
      body: PageView(
        physics: const NeverScrollableScrollPhysics(),
        controller: pageController,
        children: const [
          YouTubeScreen(),
          PipScreen(),
          SettingScreen()
        ],
      )
      // tabList[selectedIndex]
    );
    

    Use pageview in body and you got what you want
    thanks

    Login or Signup to reply.
  2. var _currentIndex = 0;
    PageController pageController = PageController();  
    
    itemChaned(index) {
      setState(() {
        _currentIndex = index;
      });
      pageController.jumpToPage(index);
    }
    
    Scaffold(
      appBar: AppBar(
        title: const Text("PageView and BottmNavigationBar"),
      ),
      body: PageView(
        controller: pageController,
        onPageChanged: itemChaned,
        children: [
          Center(
            child: Text("Home"),
          ),
          Center(
            child: Text("Profile"),
          ),
          Center(
            child: Text("Settings"),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: "Home",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: "Profile",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: "Settings",
          )
        ],
        currentIndex: _currentIndex,
        onTap: itemChaned,
      ),
    );
    

    You can use PageView and BottomNavigationBar together. I hope it’ll help you.

    Login or Signup to reply.
  3. Please try this and let me know if it meets your requirement

    Solution 1: Using Bottom Navigation Bar

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, this.title}) : super(key: key);
    
      final String? title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int bottomSelectedIndex = 0;
    
      List<BottomNavigationBarItem> buildBottomNavBarItems() {
        return [
          BottomNavigationBarItem(icon: new Icon(Icons.home), label: 'Red'),
          BottomNavigationBarItem(
            icon: new Icon(Icons.search),
            label: 'Blue',
          ),
          BottomNavigationBarItem(icon: Icon(Icons.info_outline), label: 'Yellow')
        ];
      }
    
      PageController pageController = PageController(
        initialPage: 0,
        keepPage: true,
      );
    
      Widget buildPageView() {
        return PageView(
          controller: pageController,
          onPageChanged: (index) {
            pageChanged(index);
          },
          children: <Widget>[
            Red(),
            Blue(),
            Yellow(),
          ],
        );
      }
    
      @override
      void initState() {
        super.initState();
      }
    
      void pageChanged(int index) {
        setState(() {
          bottomSelectedIndex = index;
        });
      }
    
      void bottomTapped(int index) {
        setState(() {
          bottomSelectedIndex = index;
          pageController.animateToPage(index,
              duration: Duration(milliseconds: 500), curve: Curves.ease);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('TITLE'),
          ),
          body: buildPageView(),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: bottomSelectedIndex,
            onTap: (index) {
              bottomTapped(index);
            },
            items: buildBottomNavBarItems(),
          ),
        );
      }
    }
    

    Solution 2: Without using Bottom Navigation Bar

    class ImageFullViewScreen extends StatefulWidget {
      const ImageFullViewScreen({
        Key? key,
      }) : super(key: key);
    
      @override
      ImageFullViewScreenState createState() => ImageFullViewScreenState();
    }
    
    class ImageFullViewScreenState extends State<ImageFullViewScreen> {
      List imagesList = [
        'https://picsum.photos/250?image=9',
        'https://images.unsplash.com/photo-1547721064-da6cfb341d50',
        'https://resize.hswstatic.com/u_0/w_480/gif/hybrid-tea-rose-1.jpg',
        'https://media.istockphoto.com/id/1368424494/photo/studio-portrait-of-a-cheerful-woman.jpg?s=1024x1024&w=is&k=20&c=9eszAhNKMRzMHVp4wlmFRak8YyH3rAU8re9HjKA6h3A='
      ];
      int currentPageIndex = 0;
      PageController? pageViewController;
      ValueNotifier<bool> refreshList = ValueNotifier(false);
    
      @override
      void initState() {
        super.initState();
        pageViewController =
            PageController(initialPage: currentPageIndex, keepPage: true);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.black38,
          appBar: PreferredSize(
            preferredSize: const Size.fromHeight(60.0),
            child: AppBar(
                automaticallyImplyLeading: false,
                systemOverlayStyle: SystemUiOverlayStyle.dark,
                backgroundColor: Colors.black38,
                centerTitle: true,
                titleSpacing: 0.0,
                elevation: 0.0,
                actions: [
                  IconButton(
                    onPressed: () {
                      Navigator.pop(context);
                    },
                    // ignore: prefer_const_constructors
                    icon: Icon(
                      Icons.cancel,
                      size: 38,
                      color: Colors.white,
                    ),
                  ),
                ]),
          ),
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              SizedBox(
                height: MediaQuery.of(context).size.height * 0.7,
                child: PageView.builder(
                  scrollDirection: Axis.horizontal,
                  controller: pageViewController,
                  onPageChanged: (int pageChangeIndex) {
                    currentPageIndex = pageChangeIndex;
                    refreshList.value = !refreshList.value;
                  },
                  itemBuilder: (context, index) {
                    currentPageIndex = index;
                    return Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Container(
                          padding: const EdgeInsets.symmetric(
                            horizontal: 10.0,
                          ),
                          height: MediaQuery.of(context).size.height * 0.70,
                          width: MediaQuery.of(context).size.width,
                          child: InteractiveViewer(
                              child: Image.network(
                            imagesList[currentPageIndex] ?? "",
                            filterQuality: Platform.isIOS
                                ? FilterQuality.medium
                                : FilterQuality.low,
                            loadingBuilder: (BuildContext context, Widget child,
                                ImageChunkEvent? loadingProgress) {
                              if (loadingProgress == null) {
                                return child;
                              }
                              return Container(
                                height: MediaQuery.of(context).size.height * 0.30,
                                width: MediaQuery.of(context).size.width,
                                color: Colors.grey[300]!,
                              );
                            },
                            errorBuilder: (context, error, stackTrace) {
                              return Container(
                                height: MediaQuery.of(context).size.height * 0.30,
                                width: MediaQuery.of(context).size.width,
                                color: Colors.grey[300]!,
                              );
                            },
                          )),
                        ),
                      ],
                    );
                  },
                  itemCount: imagesList.length,
                ),
              ),
              if (imagesList != null &&
                  imagesList.isNotEmpty &&
                  imagesList.length > 1)
                ValueListenableBuilder(
                  valueListenable: refreshList,
                  builder: (context, value, child) {
                    return Container(
                      alignment: Alignment.bottomCenter,
                      height: MediaQuery.of(context).size.height * 0.12,
                      width: MediaQuery.of(context).size.width,
                      padding: const EdgeInsets.only(
                        top: 25.0,
                        left: 15.0,
                        right: 15.0,
                        bottom: 5.0,
                      ),
                      child: Align(
                        alignment: Alignment.center,
                        child: ListView.separated(
                          shrinkWrap: true,
                          scrollDirection: Axis.horizontal,
                          controller: ScrollController(),
                          addAutomaticKeepAlives: false,
                          addRepaintBoundaries: false,
                          itemBuilder: (BuildContext context, int listViewIndex) {
                            return InkWell(
                              onTap: () {
                                currentPageIndex = listViewIndex;
                                pageViewController?.jumpToPage(currentPageIndex);
                              },
                              child: Container(
                                height: 20.0,
                                width: 55.0,
                                decoration: BoxDecoration(
                                  borderRadius: const BorderRadius.all(
                                    Radius.circular(4.0),
                                  ),
                                  border: Border.fromBorderSide(
                                    BorderSide(
                                      color: currentPageIndex == listViewIndex
                                          ? Colors.white
                                          : Colors.black38,
                                      width: 2.0,
                                    ),
                                  ),
                                ),
                                child: ClipRRect(
                                  borderRadius: currentPageIndex != listViewIndex
                                      ? const BorderRadius.all(Radius.circular(4.0))
                                      : const BorderRadius.all(
                                          Radius.circular(0.0)),
                                  child: InteractiveViewer(
                                    child: Image.network(
                                      imagesList[listViewIndex] ?? "",
                                      fit: BoxFit.contain,
                                      height: 40.0,
                                      width: MediaQuery.of(context).size.width,
                                      filterQuality: Platform.isIOS
                                          ? FilterQuality.medium
                                          : FilterQuality.low,
                                      loadingBuilder: (BuildContext context,
                                          Widget child,
                                          ImageChunkEvent? loadingProgress) {
                                        if (loadingProgress == null) {
                                          return child;
                                        }
                                        return Container(
                                          height: 40.0,
                                          width: MediaQuery.of(context).size.width,
                                          color: Colors.grey[300]!,
                                        );
                                      },
                                      errorBuilder: (context, error, stackTrace) {
                                        return Container(
                                          height: 40.0,
                                          width: MediaQuery.of(context).size.width,
                                          color: Colors.grey[300]!,
                                        );
                                      },
                                    ),
                                  ),
                                ),
                              ),
                            );
                            // );
                          },
                          separatorBuilder: (context, index) {
                            return const SizedBox(
                              width: 10.0,
                            );
                          },
                          itemCount: imagesList.length,
                        ),
                      ),
                    );
                  },
                ),
            ],
          ),
        );
      }
    }
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search