Flutter 颤振:在使用PageController.page生成PageView之前,无法访问它

Flutter 颤振:在使用PageController.page生成PageView之前,无法访问它,flutter,dart,flutter-pageview,Flutter,Dart,Flutter Pageview,如何解决异常- 未处理的异常:“package:flatter/src/widgets/page_view.dart”:失败的断言:第179行pos 7:“positions.isNotEmpty”:在生成PageView之前,无法访问PageController.page 注意:-我在两个屏幕中使用了它,当我在屏幕之间切换时,它会显示上述异常 @override void initState() { super.initState(); WidgetsBinding.i

如何解决异常-

未处理的异常:“package:flatter/src/widgets/page_view.dart”:失败的断言:第179行pos 7:“positions.isNotEmpty”:在生成PageView之前,无法访问PageController.page

注意:-我在两个屏幕中使用了它,当我在屏幕之间切换时,它会显示上述异常

@override
  void initState() {
    super.initState();
      WidgetsBinding.instance.addPostFrameCallback((_) => _animateSlider());
  }

  void _animateSlider() {
    Future.delayed(Duration(seconds: 2)).then(
      (_) {
        int nextPage = _controller.page.round() + 1;

        if (nextPage == widget.slide.length) {
          nextPage = 0;
        }

        _controller
            .animateToPage(nextPage,
                duration: Duration(milliseconds: 300), curve: Curves.linear)
            .then(
              (_) => _animateSlider(),
            );
      },
    );
  }

我没有足够的信息来准确了解您的问题所在,但我遇到了一个类似的问题,我想在同一个小部件中对页面视图和标签进行分组,并想将当前幻灯片和标签标记为活动状态,因此我需要访问
controler.page
,以便执行此操作。以下是我的解决方案:

修复了在使用
FutureBuilder
小部件构建
PageView
小部件之前访问页面索引的问题
class Carousel扩展了无状态小部件{
最终页面控制器;
转盘({this.controller});
///用于在构建小部件时触发事件
未来初始化控制器(){
Completer Completer=新的Completer();
///小部件完全构建后调用的回调
WidgetsBinding.instance.addPostFrameCallback((时间戳){
完成符。完成(真);
});
返回completer.future;
}///initializeController()
小部件构建(构建上下文){
返回堆栈(
儿童:[
//****修复****//
未来建设者(
future:InitializeControl(),
生成器:(BuildContext上下文,异步快照快照){
如果(!snap.hasData){
//只需返回一个占位符小部件,这里什么都没有,但您必须返回一些内容以避免错误
返回SizedBox();
}
//然后,如果构建了页面视图,我们将返回标签按钮
返回列(
儿童:[
自定义标签按钮(
子项:文本(“标签1”),
isActive:controller.page.round()==0,
按下:(){},
),
自定义标签按钮(
子项:文本(“标签2”),
isActive:controller.page.round()==1,
按下:(){},
),
自定义标签按钮(
子项:文本(“标签3”),
isActive:controller.page.round()==2,
按下:(){},
),
],
);
},
),
//******/修复****//
页面浏览(
物理:弹跳CrollPhysics(),
控制器:控制器,
儿童:[
CustomPage(),
CustomPage(),
CustomPage(),
],
),
],
);
}
}
如果需要直接在页面视图子项中使用索引,请修复此问题 您可以改用有状态小部件:

class Carousel扩展StatefulWidget{
转盘();
@凌驾
_HomeHorizontalCarouseState createState()=>U carouseState();
}
类_CarouselState扩展状态{
final PageController=PageController();
int currentIndex=0;
@凌驾
void initState(){
super.initState();
///附加一个侦听器,该侦听器将更新状态并刷新页面索引
controller.addListener(){
if(controller.page.round()!=currentIndex){
设置状态(){
currentIndex=controller.page.round();
});
}
});
}
@凌驾
无效处置(){
controller.dispose();
super.dispose();
}
小部件构建(构建上下文){
返回堆栈(
儿童:[
纵队(
儿童:[
自定义标签按钮(
子项:文本(“标签1”),
isActive:currentIndex==0,
按下:(){},
),
自定义标签按钮(
子项:文本(“标签2”),
isActive:currentIndex==1,
按下:(){},
),
自定义标签按钮(
子项:文本(“标签3”),
isActive:currentIndex==2,
按下:(){},
),
]
),
页面浏览(
物理:弹跳CrollPhysics(),
控制器:控制器,
儿童:[
CustomPage(isActive:currentIndex==0),
CustomPage(isActive:currentIndex==1),
CustomPage(isActive:currentIndex==2),
],
),
],
);
}
}

我想你可以使用这样一个监听器:

int _currentPage;

  @override
  void initState() {
    super.initState();
    _currentPage = 0;
    _controller.addListener(() {
      setState(() {
        _currentPage = _controller.page.toInt();
      });
    });
  }

这意味着您正试图访问
PageController.page
(可以是您,也可以是第三方软件包,如page Indicator),但此时,flatter尚未呈现引用控制器的
PageView
小部件

最佳解决方案:将
FutureBuilder
Future.value
在这里,我们只需使用
pageController
上的
page
属性将代码包装到未来的生成器中,这样在呈现
PageView
之后,代码就会呈现出来

我们使用
Future.value(true)
,这将导致Future立即完成,但仍然需要等待足够的时间才能成功完成下一帧,因此在我们引用它之前,
PageView
将已经生成

class Carousel extends StatelessWidget {

  final PageController controller;

  Carousel({this.controller});

  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[

        FutureBuilder(
          future: Future.value(true),
          builder: (BuildContext context, AsyncSnapshot<void> snap) {
            
            //If we do not have data as we wait for the future to complete,
            //show any widget, eg. empty Container
            if (!snap.hasData) {
             return Container();
            }

            //Otherwise the future completed, so we can now safely use the controller.page
            return Text(controller.controller.page.round().toString);
          },
        ),

        //This PageView will be built immediately before the widget above it, thanks to
        // the FutureBuilder used above, so whenever the widget above is rendered, it will
        //already use a controller with a built `PageView`        

        PageView(
          physics: BouncingScrollPhysics(),
          controller: controller,
          children: <Widget>[
           AnyWidgetOne(),
           AnyWidgetTwo()
          ],
        ),
      ],
    );
  }
}

你能告诉我你使用pageViewController的全部代码吗?它对我有用,谢谢!帮我解决了,谢谢!
 WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
     //Future will be completed here 
     // e.g completer.complete(true);
    });