Flutter中如何将子widget的整数值传递给父widget
Flutter子导航栏向父页面传值实现方案
当前场景是典型的Flutter父子组件通信场景,用回调传值+状态上提的方式实现成本最低,也符合Flutter单向数据流的设计规范,不需要引入额外的第三方依赖。
核心思路
把currentPage页码状态统一提升到父组件RootPage持有,子组件CustomNavBar不再单独维护页码状态,只负责接收父组件传入的当前页码做选中态渲染,点击导航项时通过回调函数把新的页码传回父组件,父组件收到新值后更新自身状态,同步刷新页面内容和导航栏选中态。
第一步:修改CustomNavBar组件代码
给组件新增两个必传入参:当前选中页码、页码变化回调,删除组件内部维护的currentPage变量,点击导航项时触发回调传值,修改后代码如下:
import 'package:flutter/material.dart'; import 'package:my_app/theme.dart'; class CustomNavBar extends StatefulWidget { final int currentPage; final ValueChanged<int> onPageChanged; const CustomNavBar({ Key? key, required this.currentPage, required this.onPageChanged, }) : super(key: key); @override State<CustomNavBar> createState() => _CustomNavBarState(); } class _CustomNavBarState extends State<CustomNavBar> { @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.all(0), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(24), topRight: Radius.circular(24), ), ), color: primaryColor, child: Row( children: <Widget>[ Expanded(child: navBarItem(0, Icons.home)), Expanded(child: navBarItem(1, Icons.looks_one_rounded)), Expanded(child: navBarItem(2, Icons.looks_two_rounded)), Expanded(child: navBarItem(3, Icons.looks_3_rounded)), ], ), ); } Widget navBarItem( int index, IconData icon, ) { return GestureDetector( onTap: () { widget.onPageChanged(index); }, child: Container( height: 80, width: MediaQuery.of(context).size.width / 4, decoration: const BoxDecoration( color: Colors.transparent, ), child: Icon( icon, color: index == widget.currentPage ? Colors.white : primaryAccentColor, ), ), ); } }
第二步:修改RootPage父组件代码
父组件本身已经持有currentPage状态,只需要在渲染CustomNavBar时传入当前页码,同时实现回调接收子组件传回的新页码,调用setState更新状态即可,修改后代码如下:
import 'package:flutter/material.dart'; import 'package:my_app/Pages/home_page.dart'; import 'package:my_app/Pages/profile_page.dart'; import 'package:my_app/Pages/testing_page.dart'; import 'package:my_app/Pages/testing_page2.dart'; import 'package:my_app/widgets/custom_navbar_widget.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( debugShowCheckedModeBanner: false, home: RootPage(), ); } } class RootPage extends StatefulWidget { const RootPage({Key? key}) : super(key: key); @override State<RootPage> createState() => _RootPageState(); } class _RootPageState extends State<RootPage> { int currentPage = 0; List<Widget> pages = [ const HomePage(), const ProfilePage(), const TestingPage(), const TestingPage2(), ]; @override Widget build(BuildContext context) { return SafeArea( top: false, child: Scaffold( extendBody: true, body: pages[currentPage], bottomNavigationBar: CustomNavBar( currentPage: currentPage, onPageChanged: (int newPage) { setState(() { currentPage = newPage; }); }, ), ), ); } }
补充说明
- 该方案是Flutter父子组件通信的标准实现,没有额外依赖,不会出现状态不同步的问题
- 如果后续需要跨多层组件共享页码状态,再考虑引入Provider、Riverpod等全局状态管理方案即可,当前场景用回调完全满足需求
内容的提问来源于stack exchange,提问作者Chase B.
相关产品推荐
相关产品推荐

