Home > Net >  Comunication between drawer menu and pageview [flutter]
Comunication between drawer menu and pageview [flutter]

Time:05-19

I would like to: when user tapped drawer menu item, change the pageview's index which is located at main screen.

I tried to change index from another file but I couldn't

drawer menu code

InkWell(
            onTap: () {
              debugPrint("Tapped");
              HomeApp().openMyGloves();
            },
)

openMyGloves()


class HomeApp extends StatefulWidget {
  const HomeApp({Key? key}) : super(key: key);

  @override
  State<HomeApp> createState() => _HomeAppState();

  void openMyGloves() {
    _HomeAppState()._openMyGloves();
  }
}

class _HomeAppState extends State<HomeApp> {

class _HomeAppState extends State<HomeApp> {
  int simdikiIndex = 1;
  late List<Widget> tumSayfalar;
  late Blog blogSayfa;
  late MyGloves gloveSayfa;
  late HomePage homeSayfa;
  late final controller;

  @override
  void initState() {
    blogSayfa = const Blog();
    gloveSayfa = const MyGloves();
    homeSayfa = const HomePage();
    tumSayfalar = [blogSayfa, homeSayfa, gloveSayfa];
    controller = PageController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        drawer: const DrawerMenu(),
        bottomNavigationBar: bottomNav(),
        body: PageView(

            /// [PageView.scrollDirection] defaults to [Axis.horizontal].
            /// Use [Axis.vertical] to scroll vertically.
            controller: controller,
            children: <Widget>[blogSayfa, homeSayfa, gloveSayfa],
            onPageChanged: (page) {
              setState(() {
                simdikiIndex = page;
              });
            }));
  }

  BottomNavigationBar bottomNav() {
    return BottomNavigationBar(
      items: <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Image.asset(
            "assets/images/info.png",
            scale: 2,
          ),
          label: "HAKKIMIZDA",
        ),
        BottomNavigationBarItem(
          icon: Image.asset(
            "assets/images/home.png",
            scale: 2,
          ),
          label: "ANA SAYFA",
        ),
        BottomNavigationBarItem(
          icon: Image.asset(
            "assets/images/gloves.png",
            scale: 2,
          ),
          label: "ELDİVENLERİM",
        ),
      ],
      onTap: (index) {
        setState(() {
          simdikiIndex = index;
          controller.jumpToPage(index);
        });
      },
      currentIndex: simdikiIndex,
    );
  }

  void _openMyGloves() {
    controller.jumpToPage(2);
  }
}
}

note: I got

Late Initialization Error

for controller.for controller.for controller.for controller.for controller.for controller.for controller.for controller.for controller.for controller.for controller.for controller.

CodePudding user response:

HomeApp().openMyGloves();

Here you are calling openMyGloves() from a new instance of the HomeApp which is not the one that exists in the widget tree

to solve this you have to access the same HomeApp which is built in the widget tree, this will be done by these steps:

1- Make _HomeAppState not private by removing the underscore _

2- define a global key with the HomeAppState in the parent widget of the HomeApp and pass it to HomeApp widget

  static final GlobalKey<HomeAppState> homeAppKey = GlobalKey();

then

child: HomeApp(key: homeAppKey),

now you can call openMyGloves() using this key like this

ParentWidget.homeAppKey.currentState?.openMyGloves();

ParentWidget is the parent class of HomeApp in which you define the key and pass it to HomeApp

CodePudding user response:

It'll be way easier if you pass the page view value you want to access to the parent widget, in your case HomeApp(), the code should look like this:

class DrawerMenu extends StatefulWidget {
  Function pageViewIndex;
  DrawerMenu({required this.pageViewIndex});
  @override
  _DrawerMenuState createState() => _DrawerMenuState();
}

class _DrawerMenuState extends State<DrawerMenu> {
  @override
  Widget build(BuildContext context) {
    return DrawerMenuItem(
      child: Text(item),
      onPressed: () {
        widget.pageViewIndex(x);
        // Where x equals the value you want to pass to HomeApp()
      }
    );
  }
}

Once you did that, you can now read that value from HomeApp() by using a function like this:

// This function goes to HomeApp()
void function(pageViewIndex) {
  setState(() {
    simdikiIndex = pageViewIndex;
  });
}

A different approach would be working with Provider, but if you're not familiarized with it the approach I just gave you should do the trick

  • Related