Flutter передача данных и вызов метода из виджета с отслеживанием состояния в другой statefulwidget

#flutter #dart #statefulwidget

#flutter #dart #statefulwidget

Вопрос:

Добрый день! Здесь у меня есть несколько блоков кодов моей страницы и ящика главного меню. Мне нужно передать данные из MainMenu, который является statefulwidget, в ящик, который также является statefulwidget, чтобы я мог использовать данные и метод из MainMenu. Может кто-нибудь помочь мне или воспроизвести мой код ниже.

 class MainMenu extends StatefulWidget {

  
  final VoidCallback signOut;

  MainMenu(this.signOut);
  

  @override
  _MainMenuState createState() => _MainMenuState();
}

class _MainMenuState extends State<MainMenu> {

  int index = 0;
 

  List<Widget> list = [
    HomeScreen(),
    Stations(),
    AccountPage(),

    
  ];

  signOut() {
    setState(() {
      widget.signOut();
    });
  }

  int currentIndex = 0;
  String selectedIndex = 'TAB: 0';

  String email = "", id = "", fname= "";
  TabController tabController;

  

  getPref() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    setState(() {
       id = preferences.getString('id');
       email = preferences.getString('email');
       fname = preferences.getString('fname');
    
    
    });
    print("id:"   id);
    print("user:"   email);
    print("address:"   fname);

  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getPref();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          actions: <Widget>[
          IconButton(
            onPressed: () {
              signOut();
            },
            icon: Icon(Icons.lock_open),
          )
        ],
          backgroundColor: Color(0xFF262AAA),
           iconTheme: IconThemeData(color: Colors.lightBlue),
          centerTitle: true,
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('DVO',
            style: TextStyle(color: Colors.lightBlue,fontWeight: FontWeight.w700),
            ),
            SizedBox(width: 1.3),
            Text(
              'REPORT',
              style: TextStyle(color: Colors.white,fontWeight: FontWeight.w700),
            ),
          ],
        ),
        elevation: 0,
      ),
        body: list[index],
        drawer:  MyDrawer(onTap: (lol, i) {
          setState(() {
            index = i;
            Navigator.pop(lol);
          });
        }),
      ),
    );
  }
}

class MyDrawer extends StatefulWidget {
    

    @override
  _MyDrawerState createState() => _MyDrawerState();
}

    
 class _MyDrawerState extends State<MyDrawer> { 

   Function onTap;
   _MyDrawerState(
    {this.onTap
    });
  
  

  @override
  Widget build(BuildContext context) {
    
    return SizedBox(
      width: MediaQuery
          .of(context)
          .size
          .width * 0.7,
      child: Drawer(
        child: Container(
          color: Colors.white,
          child: ListView(
            padding: EdgeInsets.all(0),
            children: <Widget>[
              
              UserAccountsDrawerHeader(
                decoration: BoxDecoration(
                color: Colors.white,
                 image: DecorationImage(
                  image: AssetImage("assets/badge.jpg"),
                     fit: BoxFit.cover,
                      colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.8), BlendMode.dstATop)),
               ),
                accountEmail: Text("dummy@gmail.com"),
                accountName: Text("Dummy", 
                style: TextStyle(color: Colors.white,fontWeight: FontWeight.w700, fontSize: 25),
                ),
                currentAccountPicture: CircleAvatar(
                  backgroundColor: Colors.grey[400],
                  child: Icon(
                            Icons.perm_identity,
                            color: Colors.white,
                  ),
                
                ),
              ),
              ListTile(
                selected: true,
                leading: Icon(Icons.announcement, color: Colors.cyan,size: 26.0),
                title: Text("News And Announcements", 
               
                style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
                ),
                onTap: () => onTap(context, 0),
                
              ),
              ListTile(
                leading: Icon(Icons.place,color: Colors.cyan, size: 30.0),
                title: Text("Stations",
                style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
                ),
                onTap: () => onTap(context, 1),
              ),
              ListTile(
                leading: Icon(Icons.settings,color: Colors.cyan, size: 30.0),
                title: Text("Account Settings",
                style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
                ),
                 onTap: () => onTap(context, 2),
              ),
               Divider(
                        height: 595,
                        thickness: 0.5,
                        color: Colors.white.withOpacity(0.3),
                        indent: 32,
                        endIndent: 32,
                      ),
               ListTile(
                leading: Icon(Icons.exit_to_app,color: Colors.cyan, size: 30.0),
                 onTap: () {
                 //widget.signOut();
                  },
                title: Text("Logout",
                style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
              
                ),
              ),
         
            ],
          ),
        ),
      ),
    );
  }
}

  

Я получаю эту ошибку при сборке виджета в MainMenu.

Именованный параметр ‘onTap’ не определен. Попробуйте исправить имя на имя существующего именованного параметра или определить именованный параметр с именем ‘onTap’.

Ответ №1:

Эта часть:

 Function onTap;

_MyDrawerState({this.onTap});
  

Этот параметр и его присутствие в конструкторе должны находиться в MyDrawer общедоступном классе, а не в частном классе состояния.

Указанная ошибка возникает из MyDrawer -за того, что класс не имеет этого.

Вы можете получить доступ onTap _MyDrawerState к функции через widget переменную, которая является экземпляром MyDrawer класса

Комментарии:

1. Как мне сделать этот доступ. извините, я новичок. Спасибо! @Arvind

2. Замените вхождения onTap(context, 0) на widget.onTap(context, 0)