结合命名路由和 PageView

Combine named Routes and PageView

我对 flutter 和构建我的第一个真正的应用程序还很陌生。我实现了一个路由器 class 并从用于导航的图标按钮生成命名路由。下一步我也想通过滑动在 3 个屏幕之间切换。

我的结构是:

main.dart (returns MaterialApp)  
FirstScreen.dart (returns Scaffold)  
SecondScreen.dart (returns Scaffold)  
ThirdScreen.dart (returns Scaffold)

我试图通过向 main.dart 添加一个网页浏览小部件来实现滑动功能,但是当我切换到使用 IconButtons 导航并切换到另一个屏幕时,滑动功能将不再起作用。我想问题很明显,因为我不再使用 main.dart 它不会加载 PageView。但是我缺少一种集成这两个功能的简洁方法。

很高兴能得到每一个帮助,提前致谢!

您真的需要使用命名路由进行导航吗?

如果没有,那么您只需为您的 PageView 添加一个 PageController 并在您的 IconButtons 中使用 nextPage/previousPage 功能。这只是通过 PageController 进行导航的粗略示例。

class SamplePageView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    PageController pageController = PageController(initialPage: 0);
    return PageView(
      controller: pageController,
      children: [
        Container(
          child: Column(
            children: [
              Text('First page'),
              Row(
                children: [
                  FlatButton(
                    color: Colors.orange,
                    child: Text('Next'),
                    onPressed: () => pageController.nextPage(
                        duration: Duration(milliseconds: 100),
                        curve: Curves.ease),
                  )
                ],
              )
            ],
          ),
        ),
        Container(
          child: Column(
            children: [
              Text('Second page'),
              Row(
                children: [
                  FlatButton(
                    color: Colors.yellow,
                    child: Text('Previous'),
                    onPressed: () => pageController.previousPage(
                        duration: Duration(milliseconds: 100),
                        curve: Curves.ease),
                  ),
                  FlatButton(
                    color: Colors.orange,
                    child: Text('Next'),
                    onPressed: () => pageController.nextPage(
                        duration: Duration(milliseconds: 100),
                        curve: Curves.ease),
                  )
                ],
              )
            ],
          ),
        ),
        Container(
          child: Column(
            children: [
              Text('Third page'),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  FlatButton(
                    color: Colors.yellow,
                    child: Text('Previous'),
                    onPressed: () => pageController.previousPage(
                        duration: Duration(milliseconds: 100),
                        curve: Curves.ease),
                  ),
                ],
              )
            ],
          ),
        ),
      ],
    );
  }
}

我还有点卡壳。如何在多个屏幕之间传递 PageController,以便调用它的方法?

我当前的代码:

main.dart

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'WeinCheckerApp',
      home: PageViewScreen(),
    );
  }
}

class PageViewScreen extends StatefulWidget {
  @override
  _PageViewScreenState createState() => _PageViewScreenState();
}

class _PageViewScreenState extends State<PageViewScreen> {
  PageController _pageController = PageController(
    initialPage: 1,
  );

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[800],
      appBar: AppBar(
        backgroundColor: Colors.red[900],
        title: Center(child: Text("WeinCheckerApp")),
      ),
      body: PageView(
        controller: _pageController,
        children: [
          SearchScreen(),
          ScanScreen(),
          FavScreen(),
        ],
      ),
    );
  }
}

ScanScreen.dart(当前3个屏幕之一都一样):

class ScanScreen extends StatefulWidget {
  @override
  _ScanScreenState createState() => _ScanScreenState();
}

class _ScanScreenState extends State<ScanScreen> {
  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return SafeArea(
      minimum: EdgeInsets.only(
        left: SizeConfig.safeBlockVertical,
        right: SizeConfig.safeBlockVertical,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Expanded(
                child: IconButton(
                  icon: Icon(Icons.search),
                  color: Colors.white,
                  onPressed: () => {},
                  iconSize: SizeConfig.safeBlockVertical * 5,
                ),
              ),
              Ink(
                decoration:
                    ShapeDecoration(shape: CircleBorder(), color: Colors.white),
                child: IconButton(
                  icon: Icon(Icons.camera_alt),
                  color: Colors.grey[800],
                  onPressed: () => print("ScanButtonPressed"),
                  iconSize: SizeConfig.safeBlockVertical * 6,
                ),
              ),
              Expanded(
                child: IconButton(
                  icon: Icon(Icons.star),
                  color: Colors.white,
                  onPressed: () => {},
                  iconSize: SizeConfig.safeBlockVertical * 5,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

图标按钮应该指向其他屏幕。

你可以只传递页面控制器。这是同一个例子,但有你的问题。

class SamplePageView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    PageController pageController = PageController(initialPage: 0);
    return PageView(
      controller: pageController,
      children: [
        First(pageController: pageController),
        Second(pageController: pageController),
        Third(pageController: pageController),
      ],
    );
  }
}

class Third extends StatelessWidget {
  const Third({
    Key key,
    @required this.pageController,
  }) : super(key: key);

  final PageController pageController;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Text('Third page'),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              FlatButton(
                color: Colors.yellow,
                child: Text('Previous'),
                onPressed: () => pageController.previousPage(
                    duration: Duration(milliseconds: 100), curve: Curves.ease),
              ),
            ],
          )
        ],
      ),
    );
  }
}

class Second extends StatelessWidget {
  const Second({
    Key key,
    @required this.pageController,
  }) : super(key: key);

  final PageController pageController;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Text('Second page'),
          Row(
            children: [
              FlatButton(
                color: Colors.yellow,
                child: Text('Previous'),
                onPressed: () => pageController.previousPage(
                    duration: Duration(milliseconds: 100), curve: Curves.ease),
              ),
              FlatButton(
                color: Colors.orange,
                child: Text('Next'),
                onPressed: () => pageController.nextPage(
                    duration: Duration(milliseconds: 100), curve: Curves.ease),
              )
            ],
          )
        ],
      ),
    );
  }
}

class First extends StatelessWidget {
  const First({
    Key key,
    @required this.pageController,
  }) : super(key: key);

  final PageController pageController;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Text('First page'),
          Row(
            children: [
              FlatButton(
                color: Colors.orange,
                child: Text('Next'),
                onPressed: () => pageController.nextPage(
                    duration: Duration(milliseconds: 100), curve: Curves.ease),
              )
            ],
          )
        ],
      ),
    );
  }
}