如何使用一个按钮有条件地路由? (颤振)

时间:2018-08-04 12:23:44

标签: dart flutter

我有一个场景(collections.dart),该场景在PageView.builder中采用了其他几个场景/文件的索引。您可以在collections.dart文件中的场景之间滑动。在collections.dart中也有一个按钮。

我希望是这样的,如果您单击按钮,并且当前通过collections.dart显示的场景是FirstScreen,那么我可以路由到我专门构建的表对于first.dart,索引中的所有其他场景都适用。

我尝试通过在onPressed参数中使用条件语句来完成此操作,但尚未成功。没有错误,它仅需采取任何措施。这是collections.dart的完整代码(包括onPressed失败的条件语句):

    import 'package:flutter/material.dart';
    import 'package:circle_indicator/circle_indicator.dart';
    import 'first.dart';
    import 'second.dart';
    import 'third.dart';
    import 'fourth.dart';
    import 'fifth.dart';
    import 'sixth.dart';
    import 'seventh.dart';
    import 'eighth.dart';
    import 'ninth.dart';
    import 'tenth.dart';


    class CollectionsScreen extends StatelessWidget {

      @override
      Widget build(BuildContext context){
        return Collections();
      }
    }

    class Collections extends StatefulWidget {
      @override
      CollectionsState createState() => CollectionsState();
    }

    class CollectionsState extends State<Collections> {

      FirstScreen one;
      SecondScreen two;
      ThirdScreen three;
      FourthScreen four;
      FifthScreen five;
      SixthScreen six;
      SeventhScreen seven;
      EighthScreen eight;
      NinthScreen nine;
      TenthScreen ten;
      List<Widget> pages;

      @override
      void initState() {
        one = FirstScreen();
        two = SecondScreen();
        three = ThirdScreen();
        four = FourthScreen();
        five = FifthScreen();
        six = SixthScreen();
        seven = SeventhScreen();
        eight = EighthScreen();
        nine = NinthScreen();
        ten = TenthScreen();

        pages = [one, two, three, four, five, six, seven, eight, nine, ten];

        super.initState();
      } 

      final PageController controller = new PageController();

      @override
      Widget build(BuildContext context){

        return new Stack(
          children: <Widget>[
            new Scaffold( 
              body: new Container(
                child: new PageView.builder( //Swipe Between Pages
                  controller: controller,
                  itemCount: 10,
                  itemBuilder: (context, index){
                    return pages[index];
                  }
                ),
              ),
            ),
            new Container( //CircleIndicator
              child: new CircleIndicator(controller, 10, 8.0, Colors.white70, Colors.white,),
              alignment: Alignment(0.0, 0.9),
            ),
            new Container( //Button
              alignment: Alignment(0.0, 0.65),
              child: new Row( 
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  new Container(
                    child: new RaisedButton(
                      elevation: 4.0,
                      child: new Text(
                        'SHOW ME',
                        style: new TextStyle(
                          fontWeight: FontWeight.w900,
                          fontSize: 22.0,
                        ),
                      ),
                      color: Color(0xFF70E0EF),
                      shape: new RoundedRectangleBorder(
                        borderRadius: new BorderRadius.circular(7.5)
                      ),
    //This is the conditional statement I'm talking about
                      onPressed: () { 
                        new PageView.builder(
                          controller: controller,
                          itemBuilder: (context, index) {
                            if (pages[index] == one){
                              Navigator.push(
                                context,
                                new MaterialPageRoute(builder: (context) => new FirstTable()),
                              );
                            }
                            else if (pages[index] == two){
                              Navigator.push(
                                context,
                                new MaterialPageRoute(builder: (context) => new SecondTable()),
                              );
                            }
                            else {
                              Navigator.push(
                                context,
                                new MaterialPageRoute(builder: (context) => new ThirdTable()),
                              );
                            }
                          }
                        );
                      },
                    ),
                    width: 150.0,
                    height: 60.0,
                  ),
                ],
              ),
            ),
          ],
        );
      }
    }

我在条件语句中引用的“ Table”类在first.dart,second.dart等文件中。这是first.dart的文件。目前,所有这些文件(first.dart,second.dart等)中的代码都是相同的:

    import 'package:flutter/material.dart';

    class FirstScreen extends StatelessWidget {

      @override
      Widget build(BuildContext context) {
        return new First();
      }
    }

    class First extends StatefulWidget {
      @override
      FirstState createState() => FirstState();
    }

    class FirstState extends State<First>{

      @override
      Widget build(BuildContext context) {

        double fontSize = MediaQuery.of(context).size.height;

        double fontSizeFractional = fontSize * 0.07;

        return Scaffold( 
          body: new Stack(
            fit: StackFit.passthrough,
            children: [
              new Container( //Background
                decoration: new BoxDecoration(
                  image: new DecorationImage(
                    image: new AssetImage('assets/FirstBG.png'),
                    fit: BoxFit.cover
                  ),
                ),
              ),
              new Container( //Title
                margin: EdgeInsets.all(40.0), 
                alignment: new Alignment(0.0, -0.70),
                child: new Text(
                  'FIRST',
                  style: new TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: fontSizeFractional,
                    color: Colors.white,
                    fontFamily: 'baron neue',
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }

    class FirstTable extends StatelessWidget {

      @override
      Widget build(BuildContext context) {
        return new Table();
      }
    }

    class Table extends StatefulWidget {
      @override
      TableState createState() => TableState();
    }

    class TableState extends State<Table>{
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: new RaisedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: new Text(
                'Go Back',
              ),
            ),
          ),
        );
      }
    }

我有一个理论,认为它不起作用的原因是collections.dart实际上并未缓存有关其所在索引页面的任何数据(不过,这可能是完全错误的)。好奇听到您的想法!

1 个答案:

答案 0 :(得分:1)

您的问题是您应该直接在按钮controller.page内使用onPressed。而不是实例化窗口小部件。

尽管最终您应该在图库类和项目列表之间隐藏一个抽象层。

为此,您可以创建一个自定义类,该类将收集有关图库项目的所有信息:

@immutable
class GalleryItem {
  final Widget content;
  final Widget details;

  GalleryItem({@required this.content, this.details}) : assert(content != null);
}

您的画廊然后将使用此类列表作为参数。并用这些来做。

理想情况下,您想这样使用画廊:

Gallery(
  items: [
    GalleryItem(
      content: Container(
        color: Colors.red,
      ),
      details: Text("red"),
    ),
    GalleryItem(
      content: Container(
        color: Colors.blue,
      ),
      details: Text("blue"),
    ),
  ],
),

enter image description here

此类图库的代码为:

class Gallery extends StatefulWidget {
  final List<GalleryItem> items;

  Gallery({@required this.items, Key key})
      : assert(items != null),
        super(key: key);

  @override
  _GalleryState createState() => _GalleryState();
}

class _GalleryState extends State<Gallery> {
  final PageController pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
          child: PageView(
            children: widget.items.map((item) => item.content).toList(),
            controller: pageController,
          ),
        ),
        RaisedButton(
          onPressed: showContentDetails,
          child: Text("More info"),
        )
      ],
    );
  }

  void showContentDetails() {
    final index = pageController.page.round();

    if (widget.items[index]?.details != null) {
      showDialog(
        context: context,
        builder: (_) =>
            GalleryItemDetails(details: widget.items[index].details),
      );
    }
  }
}

class GalleryItemDetails extends StatelessWidget {
  final Widget details;

  GalleryItemDetails({@required this.details, Key key})
      : assert(details != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Dialog(
      child: details,
    );
  }
}