显示空白屏幕的Flutter Navigator.push

时间:2019-11-15 04:54:24

标签: flutter flutter-layout staggered-gridview

我有一个 main.dart ,其中包含一个Default选项卡控制器。我在 Popular.dart 文件中使用了StaggeredGridView,并将其显示给TabBarView。一切正常,但是当我尝试从 Popular.dart 文件导航时,屏幕显示空白屏幕。我想从 Popular.dart 进入 ViewItem.dart 类。

这是我的代码:

main.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lamps/ViewItem.dart';

import 'Constants.dart';
import 'Popular.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        backgroundColor: Constants.BACKGROUND,
        fontFamily: 'Quicksand',
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: DefaultTabController(
        length: 4,
        initialIndex: 1,
        child: Scaffold(
          appBar: AppBar(
            elevation: 0,
            backgroundColor: Constants.BACKGROUND,
            centerTitle: true,
            title: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
              InkWell(
                child: item("assets/img/menu.png"),
                onTap: () {
                  setState(() {});
                },
              ),
              Text("Explore",
                style: TextStyle(
                    color: Constants.TITLE, fontWeight: FontWeight.bold),),

              InkWell(
                child: item("assets/img/like.png"),
                onTap: () {
                  setState(() {});
                },
              ),
            ],),

            bottom: TabBar(
              indicator: CircleTabIndicator(color: Constants.PRICE, radius: 4),
              labelColor: Constants.FONT_MAIN,
              unselectedLabelColor: Constants.FONT_OFF,
              indicatorColor: Constants.BACKGROUND,
              tabs: [
                Tab(
                  text: "New",
                ),
                Tab(text: "Popular"),
                Tab(text: "Trending"),
                Tab(text: "Best Selling"),
              ],
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              ViewItem(1),
              Popular(),
              Popular(),
              Popular(),
            ],
          ),
        ),
      ),
    );
  }

  Widget item(String image) {
    return Stack(
      alignment: Alignment.center,
      children: <Widget>[
        Container(
            height: 24,
            width: 24,
            child: DecoratedBox(
              position: DecorationPosition.background,
              decoration: BoxDecoration(
                shape: BoxShape.rectangle,
                color: Constants.ITEM_BACK,
                borderRadius: BorderRadius.all(Radius.circular(8)),
              ),
            )),
        Container(
          height: 13,
          width: 13,
          child: Image.asset(image),
        )
      ],
    );
  }
}

class CircleTabIndicator extends Decoration {
  final BoxPainter _painter;

  CircleTabIndicator({@required Color color, @required double radius})
      : _painter = _CirclePainter(color, radius);

  @override
  BoxPainter createBoxPainter([onChanged]) => _painter;
}

class _CirclePainter extends BoxPainter {
  final Paint _paint;
  final double radius;

  _CirclePainter(Color color, this.radius)
      : _paint = Paint()
          ..color = color
          ..isAntiAlias = true;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
    final Offset circleOffset =
        offset + Offset(cfg.size.width / 2, cfg.size.height - radius * 10);
    canvas.drawCircle(circleOffset, radius, _paint);
  }
}

Popular.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:lamps/ViewItem.dart';

import 'Constants.dart';

class Popular extends StatefulWidget {

  @override
  _Popular createState()=> _Popular();

}


class _Popular extends State<Popular>{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      color: Colors.white,
      child: StaggeredGridView.countBuilder(
        primary: false,
        shrinkWrap: true,
        addAutomaticKeepAlives: true,
        crossAxisCount: 4,
        itemCount: 9,
        padding: EdgeInsets.all(16),
        mainAxisSpacing: 24,
        crossAxisSpacing: 16,
        itemBuilder: (BuildContext context, int index) => GestureDetector(
          child: new Container(
            child: Stack(
              children: <Widget>[
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Hero(
                      child: Container(
                        decoration: BoxDecoration(
                            color: Constants.ITEM_BACK,
                            borderRadius: BorderRadius.all(Radius.circular(24))),
                        padding: EdgeInsets.all(16),
                        child: Image.asset(Constants.lamps[index]["image"]),
                      ),
                      tag: "image",
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Hero(
                      child: Text(Constants.lamps[index]["name"],
                          style: TextStyle(color: Constants.FONT_MAIN, fontSize: 14,fontWeight: FontWeight.bold)),
                      tag: "name",
                    ),
                    Hero(
                      child: Text(
                        Constants.lamps[index]["price"],
                        style: TextStyle(color: Constants.PRICE, fontSize: 10),
                      ),
                      tag: "price",
                    )
                  ],
                ),
                Positioned(
                    right: 14, bottom: 26, child: item("assets/img/like.png")),
              ],
            ),
          ),
          onTap: (){
            Route route = MaterialPageRoute(builder: (context) => ViewItem(2));
            Navigator.push(context, route);
          },
        ),
        staggeredTileBuilder: (int index) => new StaggeredTile.fit(2),

      ),
    );
  }

  Widget item(String image) {
    return Stack(
      alignment: Alignment.center,
      children: <Widget>[
        Container(
            height: 24,
            width: 24,
            child: DecoratedBox(
              position: DecorationPosition.background,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Constants.love_back,
              ),
            )),
        Container(
          height: 13,
          width: 13,
          child: Image.asset(image),
        )
      ],
    );
  }
}

ViewItem.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lamps/Popular.dart';

import 'Constants.dart';

class ViewItem extends StatefulWidget {
  int position;

  ViewItem(this.position);

  @override
  _ViewItem createState() => _ViewItem(position);
}

class _ViewItem extends State<ViewItem> {

  int position;
  _ViewItem(this.position);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        appBar: AppBar(
            elevation: 0,
            backgroundColor: Constants.BACKGROUND,
            centerTitle: true,
            title: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                InkWell(
                  child: item("assets/img/menu.png"),
                  onTap: () {
                    setState(() {});
                  },
                ),
                Text(
                  "Explore",
                  style: TextStyle(
                      color: Constants.TITLE, fontWeight: FontWeight.bold),
                ),
                InkWell(
                  child: item("assets/img/like.png"),
                  onTap: () {
                    Route route = MaterialPageRoute(builder: (context) => Popular());
                    Navigator.push(context, route);
                  },
                ),
              ],
            )),
        body: Stack(
          children: <Widget>[

            Column(
              children: <Widget>[

                //Image.asset(Constants.lamps[position]["name"])

              ],
            )

          ],
        ),
    );
  }

  Widget item(String image) {
    return Stack(
      alignment: Alignment.center,
      children: <Widget>[
        Container(
            height: 24,
            width: 24,
            child: DecoratedBox(
              position: DecorationPosition.background,
              decoration: BoxDecoration(
                shape: BoxShape.rectangle,
                color: Constants.ITEM_BACK,
                borderRadius: BorderRadius.all(Radius.circular(8)),
              ),
            )),
        Container(
          height: 13,
          width: 13,
          child: Image.asset(image),
        )
      ],
    );
  }
}

1 个答案:

答案 0 :(得分:1)

我认为问题出在您使用过的HeroTags上。您必须给它们唯一的值。对于当前方案,只需按照以下步骤更改Popular.dart文件中的列,

Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Hero(
                      child: Container(
                        decoration: BoxDecoration(
                            color: Colors.red,
                            borderRadius: BorderRadius.all(Radius.circular(24))),
                        padding: EdgeInsets.all(16),
                        child: Image.asset("https://blog.codemagic.io/uploads/2019/05/CM_Top-Flutter-Influencers.png"),
                      ),
                      tag: DateTime.now().toIso8601String(),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Hero(
                      child: Text("Tets",
                          style: TextStyle(color: Colors.yellow, fontSize: 14,fontWeight: FontWeight.bold)),
                      tag: DateTime.now().toIso8601String(),
                    ),
                    Hero(
                      child: Text(
                        "200",
                        style: TextStyle(color: Colors.pink, fontSize: 10),
                      ),
                      tag: DateTime.now().toIso8601String(),
                    )
                  ],
                ),

您必须给英雄标签赋予唯一的值,因为您要为TabBarView()中的Popular()小部件的所有3个实例使用英雄标签。

OR ,您也可以每次为“流行”小部件传递唯一索引,例如

TabBarView(
            children: <Widget>[
              ViewItem(1),
              Popular(1),
              Popular(2),
              Popular(3),
            ],
          ),

您的heroTag值类似于

"image${widget.index}", "name${widget.index}", "price${widget.index}",

我已经尝试过并且正在工作。