微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter - 如何在从孩子传递值的同时更改父级的主体小部件?

如何解决Flutter - 如何在从孩子传递值的同时更改父级的主体小部件?

所以,我有一个“主页”页面,它有一个脚手架、应用栏、正文和底部导航栏。 正文作为小部件从列表中加载,具体取决于在底部导航栏上单击的内容。 我希望能够按下当前加载在父主体中的子小部件中的某些东西,并将父主体的主体小部件更改为另一个子小部件,同时还将值传递给子小部件。 把它想象成在浏览器中按下 iframe 中的链接,只是 iframe 发生变化,你可以传递一个像 ?id=12 这样的值。

这是“主页”页面

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedindex = 0;
  final List<Widget> _children = [
    Page1(),Page2(),Page3(),Page4()
  ];
  void _onItemTapped(int index) {
    setState(() {
      _selectedindex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
              actions: <Widget>[
                TextButton(
                  onpressed: () {},child: Text("Log Out",style: TextStyle(color: Colors.white)),),],backgroundColor: Colors.blue.shade900,body: _children[_selectedindex],bottomNavigationBar: BottomNavigationBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.work),label: 'Page 1',BottomNavigationBarItem(
                  icon: Icon(Icons.inventory),label: 'Page 2',BottomNavigationBarItem(
                  icon: Icon(Icons.alt_route),label: 'Page 3',BottomNavigationBarItem(
                  icon: Icon(Icons.article),label: 'Page 4',currentIndex: _selectedindex,onTap: _onItemTapped,type: BottomNavigationBarType.fixed,);
  }
}

这是由 _children[_selectedindex] 通过按下底部导航栏中的按钮之一定义的子部件

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1> {

  @override
  Widget build(BuildContext context) {
    return Text("Click Here",onpressed:(){
    //objective here is to open Page5 in the body of HomePage(not in _children list of homepage,and pass it some value (ie. id 12))
            },);
  }
}

为了举例说明期望,这就是我想要在 Page5 中的内容(应该加载到 HomePage 的正文中

class Page5 extends StatefulWidget {
  @override
  _Page5State createState() => _Page5State();
}

class _Page5State extends State<Page5> {
  int _variableFromPage1;
  @override
  Widget build(BuildContext context) {
    return Text(_variableFromPage1);
  }
}

谁能建议最好的方法

解决方法

您可以像下面的代码示例一样定义自定义回调函数。

class HomePage extends StatefulWidget {      
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;
  int _selectedID = 0;

  List<Widget> _children;

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  void initState() {
    super.initState();

    _children = [
      Page1(
        callback: (value) {
          setState(() {
            _selectedID = value;
          });
        },),Page2(),];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: (_selectedIndex == 0 && _selectedID > 0)
          ? Page5(id: _selectedID)
          : _children[_selectedIndex],bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.work),label: 'Page 1',BottomNavigationBarItem(
            icon: Icon(Icons.inventory),label: 'Page 2',],currentIndex: _selectedIndex,onTap: _onItemTapped,type: BottomNavigationBarType.fixed,);
  }
}

typedef IntCallback(int value);

class Page1 extends StatelessWidget {
  Page1({Key key,@required this.callback}) : super(key: key);

  final IntCallback callback;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: InkWell(
        onTap: () {
          callback(12);
        },child: Text("Page1 ::: id >>> 12"),);
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("Page2"),);
  }
}

class Page5 extends StatelessWidget {
  Page5({Key key,@required this.id}) : super(key: key);
  
  final int id;

  @override
  Widget build(BuildContext context) {
    return Center(child: Text("Page5 ::: id $id"));
  }
}
,

你试试这个方法

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
  Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
        case "Home":
        return MaterialPageRoute(builder: (context) => Home());
      
      case "Settings":
          return MaterialPageRoute(builder: (context) => Settings());
     
      default:
         return MaterialPageRoute(builder: (context) => Default());
     
    }
  }

  void _onItemTapped(int index) {
    switch (index) {
      case 1:
        _navigatorKey.currentState!
            .pushNamedAndRemoveUntil("Home",(route) => false);
        break;
      case 2:
        _navigatorKey.currentState!
            .pushNamedAndRemoveUntil("Settings",(route) => false);
        break;
      default:
        _navigatorKey.currentState!
            .pushNamedAndRemoveUntil("Default",(route) => false);
    }
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',theme: ThemeData(
        primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,debugShowCheckedModeBanner: false,home: Scaffold(
        body: Navigator(key: _navigatorKey,onGenerateRoute: generateRoute),bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),label: 'Home',BottomNavigationBarItem(
              icon: Icon(Icons.settings),label: 'Setting',showSelectedLabels: true,showUnselectedLabels: false,selectedItemColor: Colors.white,unselectedItemColor: Color(0xFF9e9e9e),iconSize: 16,backgroundColor: Color.fromRGBO(58,66,86,1.0),);
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。