Flutter首页Column内使用PageView结合底部导航栏切换页面报错
问题描述
在Column组件的子节点中使用PageView时触发渲染报错,需求为通过该组件搭配底部导航栏实现多页面跳转功能。
以下是触发报错的完整代码:
import 'package:flutter/material.dart'; import 'package:mad_ezee_app/constants.dart'; import 'package:flutter/src/rendering/box.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { int _selectedIndex = 0; PageController pageController = PageController(); void onTapped(int index){ setState(() { _selectedIndex = index; }); pageController.jumpToPage(index); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children:[ Container( child: Container( margin: EdgeInsets.only(top:45,bottom: 15), padding: EdgeInsets.only(left: 20,right: 20), child:Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( children:[ Text("Bengaluru"), Text("R.T Nagar") ] ), Container( width: 45, height:45, child: Icon(Icons.search,color: Colors.white,), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color:TimePassColor.APP_COLOR ), ), ] ) ) ), PageView( controller: pageController, children: [ Container(color: Colors.red,), Container(color: Colors.blue,), Container(color: Colors.white,), Container(color: Colors.yellow,), ], ), ] ), bottomNavigationBar: BottomNavigationBar(items: const <BottomNavigationBarItem> [ BottomNavigationBarItem(icon: Icon(Icons.home),label:'Home'), BottomNavigationBarItem(icon: Icon(Icons.search),label:'Search'), BottomNavigationBarItem(icon: Icon(Icons.notifications),label:'Notifications'), BottomNavigationBarItem(icon: Icon(Icons.person),label:'Profile'), ],currentIndex: _selectedIndex, selectedItemColor: Colors.blue, unselectedItemColor: Colors.grey, onTap: onTapped, ) ); } }
报错截图

报错原因
这是Flutter布局中典型的垂直约束冲突:
- Column属于垂直排列布局,不会为子组件设置固定的垂直高度上限,子组件可以按自身需求占用高度
- PageView的默认布局规则是自动撑满父组件提供的全部可用垂直高度
- 两者嵌套时,PageView无法获取明确的高度边界,会出现垂直高度无限大的渲染异常,直接触发报错。
修复方法
给PageView外层包裹Expanded组件即可解决问题。Expanded会自动计算Column中除顶部固定高度头部栏之外的剩余可用垂直空间,将这部分空间分配给PageView,从根源解决约束冲突。
如果不需要支持左右滑动切换页面(仅通过点击底部导航栏切换),可以额外给PageView添加physics: NeverScrollableScrollPhysics()属性,关闭PageView的默认滑动响应,避免和其他滑动组件手势冲突。
修复后对应代码片段:
body: Column( children:[ // 原有顶部头部栏代码无需修改 Container( child: Container( margin: EdgeInsets.only(top:45,bottom: 15), padding: EdgeInsets.only(left: 20,right: 20), child:Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( children:[ Text("Bengaluru"), Text("R.T Nagar") ] ), Container( width: 45, height:45, child: Icon(Icons.search,color: Colors.white,), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color:TimePassColor.APP_COLOR ), ), ] ) ) ), // 用Expanded包裹PageView Expanded( child: PageView( controller: pageController, // 不需要左右滑动切换时打开下方注释 // physics: NeverScrollableScrollPhysics(), children: [ Container(color: Colors.red,), Container(color: Colors.blue,), Container(color: Colors.white,), Container(color: Colors.yellow,), ], ), ), ] ),
内容的提问来源于stack exchange,提问作者Sachin Rajput
相关产品推荐
相关产品推荐

