无法在 Flutter 中的 PageController 上跳转到页面
Posted
技术标签:
【中文标题】无法在 Flutter 中的 PageController 上跳转到页面【英文标题】:Can't jumpToPage on PageController in Flutter 【发布时间】:2021-04-04 10:05:31 【问题描述】:我已经构建了一个 Scaffold 屏幕,其中有一个 PageView 在 body 和一个 bottomNavigationBar。
我还为此页面构建了 Cubit + State 管理器。
当屏幕第一次打开时,我希望触发 API 调用。我还希望选择选项卡 1(在 PageView 和 bottomNavigationBar 上)。 当 API 返回响应时,我希望事件监听器更新屏幕并选择选项卡 0。
这适用于底部导航栏,但我在更新 PageView 时遇到问题。这是我的代码:
class HomeScreen extends StatefulWidget
@override
_HomeScreenState createState() => _HomeScreenState();
class _HomeScreenState extends State<HomeScreen>
int _page = 1;
PageController _c;
double iconSize = 32;
bool forceCourseEnrolment = true;
@override
void initState()
_c = new PageController(
initialPage: 1,
keepPage: false,
);
super.initState();
@override
Widget build(BuildContext context)
return BlocConsumer<HomeScreenCubit, HomeScreenState>(
listener: (context, state)
debugPrint("listener received something");
if (state is DataRetrieved)
state.enrolledCourses.length > 0
? forceCourseEnrolment = false
: forceCourseEnrolment = true;
state.enrolledCourses.length > 0 ? _page = 0 : _page = 1;
var hasClients = this._c.hasClients;
debugPrint("this._c.hasClients $hasClients");
// This prints: this._c.hasClients false
// Enabling this line:
// this._c.jumpToPage(_page);
// leads to:
// [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 112 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
, builder: (context, state)
if (state is HomeScreenInitial)
context.bloc<HomeScreenCubit>().retrieveData();
return Scaffold(
body: SpinKitChasingDots(
color: COLOR_main_purple,
size: 50.0,
));
return Scaffold(
body: PageView(
controller: _c,
onPageChanged: (newPage)
setState(()
this._page = newPage;
);
,
physics: NeverScrollableScrollPhysics(),
children: [
PurchasedCoursesTab(),
ElearningTab(),
MyPracticeTab(),
ProfileTab(),
],
),
bottomNavigationBar: SizedBox(
height: 80,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(30),
topLeft: Radius.circular(30)),
boxShadow: [
BoxShadow(
color: Colors.black38.withOpacity(0.1),
spreadRadius: 0,
blurRadius: 25),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
child: BottomNavigationBar(
currentIndex: _page,
onTap: (index)
if (forceCourseEnrolment == false)
this._c.animateToPage(index,
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut);
,
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
// title: Text(""),
title: showIndicator(_page == 0),
icon: Container(
width: iconSize,
height: iconSize,
child: SvgPicture.asset('assets/images/ic_run.svg',
color: _page == 0
? COLOR_main_purple
: forceCourseEnrolment == false
? Colors.black
: COLOR_main_text_grey_with_opacity),
)),
BottomNavigationBarItem(
title: showIndicator(_page == 1),
icon: Container(
width: iconSize,
height: iconSize,
child: SvgPicture.asset(
'assets/images/ic_e_learning.svg',
color: _page == 1
? COLOR_main_purple
: Colors.black),
)),
BottomNavigationBarItem(
title: showIndicator(_page == 2),
icon: Container(
width: iconSize,
height: iconSize,
child: SvgPicture.asset(
'assets/images/ic_journal.svg',
color: _page == 2
? COLOR_main_purple
: forceCourseEnrolment == false
? Colors.black
: COLOR_main_text_grey_with_opacity),
)),
BottomNavigationBarItem(
title: showIndicator(_page == 3),
// title: Text(_page == 3 ? "•" : "", style: TextStyle(
// color: COLOR_main_purple, fontSize: 24.0)),
icon: Container(
width: iconSize,
height: iconSize,
child: SvgPicture.asset(
'assets/images/ic_gamification.svg',
color: _page == 3
? COLOR_main_purple
: forceCourseEnrolment == false
? Colors.black
: COLOR_main_text_grey_with_opacity),
)),
],
),
)),
));
);
当我尝试在 BlocConsumer 的侦听器中更改页面时遇到的错误:
[错误:flutter/lib/ui/ui_dart_state.cc(177)] 未处理的异常: 'package:flutter/src/widgets/scroll_controller.dart': 失败 断言:第 112 行 pos 12:'_positions.isNotEmpty':ScrollController 未附加到任何滚动视图。
【问题讨论】:
【参考方案1】:发现我可以通过将以下内容添加到侦听器来使其工作:
if (state is DataRetrieved)
state.enrolledCourses.length > 0
? forceCourseEnrolment = false
: forceCourseEnrolment = true;
state.enrolledCourses.length > 0 ? _page = 0 : _page = 1;
Future.delayed(Duration(milliseconds: 50), ()
if (this._c.hasClients)
this._c.jumpToPage(_page);
);
我发现这是一个丑陋的解决方案,所以我不会将此标记为答案。如果您知道更好的处理方法,请告诉我。
【讨论】:
【参考方案2】:您可以尝试删除此代码吗?如果需要显示加载,可以尝试将其添加到 PurchasedCoursesTab 中。
if (state is HomeScreenInitial)
context.bloc<HomeScreenCubit>().retrieveData();
return Scaffold(
body: SpinKitChasingDots(
color: COLOR_main_purple,
size: 50.0,
));
出现此问题是因为此时您的 PageController
未附加到 PageView。
【讨论】:
以上是关于无法在 Flutter 中的 PageController 上跳转到页面的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 中的 AlertDialog 小部件无法使用 setState 功能
在 Flutter 中导航后无法关注新页面中的 TextField