PageController 未在 Flutter 的 PageView 模块中正确设置。位置不为空错误弹出
PageController not set properly within the PageView module in Flutter. Positions not empty error popping up
我开始使用 Flutter 框架进行编程,并立即注意到出现了一个奇怪的问题(有关详细信息,请参见下文)。
问题发生在:
返回 MainScreen
并尝试通过按下按钮从 PageView
中的屏幕切换来更改 PageView
索引后,我收到此错误:
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 110 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
这是我的主屏幕:
class MainScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => MainScreenState();
}
class MainScreenState extends State<MainScreen> {
PageController _controller;
void _onLoad() {
_controller = PageController();
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_onLoad();
return PageView(
controller: _controller,
physics: NeverScrollableScrollPhysics(),
children: [
FirstScreen(),
SecondScreen(),
],
);
}
}
这是我的 RxDart
Sharable
文件:
import 'package:rxdart/rxdart.dart';
class ShareBloc {
static ShareBloc _instance;
BehaviorSubject<dynamic> _subjectCounter;
static ShareBloc getInstance() {
if (_instance == null) _instance = ShareBloc();
return _instance;
}
ShareBloc() {
_subjectCounter = new BehaviorSubject<dynamic>();
}
Stream<dynamic> get getStream => pageViewIndexStream.stream;
void onShare(dynamic data) {
_subjectCounter.sink.add(data);
}
void dispose() {
if (_subjectCounter != null) {
_subjectCounter.close();
_instance = null;
}
}
}
谁能告诉我我做错了什么?
为我解决这个问题的正确方法是包装这部分:
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
与:
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
if (_controller.hasClients) { // <-- this is the fix!
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
}
});
//This will run just once
@override
void initState() {
super.initState();
//This code is the same as your _onLoad method, you don't neet to run it on the build method anymore
_controller = PageController();
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
}
就像 dispose 方法一样,StatefulWidget 有一个 initState 方法,它 运行 只执行一次(当它被插入到树中时)。之后,当构建方法再次 运行s 时,此代码将不会 运行.
我开始使用 Flutter 框架进行编程,并立即注意到出现了一个奇怪的问题(有关详细信息,请参见下文)。
问题发生在:
返回 MainScreen
并尝试通过按下按钮从 PageView
中的屏幕切换来更改 PageView
索引后,我收到此错误:
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 110 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
这是我的主屏幕:
class MainScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() => MainScreenState();
}
class MainScreenState extends State<MainScreen> {
PageController _controller;
void _onLoad() {
_controller = PageController();
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_onLoad();
return PageView(
controller: _controller,
physics: NeverScrollableScrollPhysics(),
children: [
FirstScreen(),
SecondScreen(),
],
);
}
}
这是我的 RxDart
Sharable
文件:
import 'package:rxdart/rxdart.dart';
class ShareBloc {
static ShareBloc _instance;
BehaviorSubject<dynamic> _subjectCounter;
static ShareBloc getInstance() {
if (_instance == null) _instance = ShareBloc();
return _instance;
}
ShareBloc() {
_subjectCounter = new BehaviorSubject<dynamic>();
}
Stream<dynamic> get getStream => pageViewIndexStream.stream;
void onShare(dynamic data) {
_subjectCounter.sink.add(data);
}
void dispose() {
if (_subjectCounter != null) {
_subjectCounter.close();
_instance = null;
}
}
}
谁能告诉我我做错了什么?
为我解决这个问题的正确方法是包装这部分:
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
与:
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
if (_controller.hasClients) { // <-- this is the fix!
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
}
});
//This will run just once
@override
void initState() {
super.initState();
//This code is the same as your _onLoad method, you don't neet to run it on the build method anymore
_controller = PageController();
ShareBloc.getInstance().pageViewIndexStream.listen((index) {
_controller.animateToPage(index,
duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
});
}
就像 dispose 方法一样,StatefulWidget 有一个 initState 方法,它 运行 只执行一次(当它被插入到树中时)。之后,当构建方法再次 运行s 时,此代码将不会 运行.