我在加载CatDetailHeader时遇到问题

时间:2020-01-08 16:58:48

标签: flutter dart

我希望一切都好。我一直在观看视频教程,但在加载第二个屏幕时遇到了麻烦。我可以看到带有猫列表的屏幕,但是我无法加载详细信息页面。我已经将示例代码复制到了我的项目中,但是没有用。我什至尝试加载示例项目,但也不起作用。我需要重新审视这种情况。

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════

The following assertion was thrown building CatDetailHeader(dirty, dependencies: [_LocalizationsScope-[GlobalKey#5f942], _InheritedTheme], state: _CatDetailHeaderState#2ac20):

'package:flutter/src/widgets/heroes.dart': Failed assertion: line 164 pos 15: 'tag != null': is not true.


The relevant error-causing widget was:

  CatDetailHeader file:///C:/Users/13363/AndroidStudioProjects/catbox/lib/ui/cat_details/details_page.dart:40:19

When the exception was thrown, this was the stack:

#2      new Hero (package:flutter/src/widgets/heroes.dart:164:15)

#3      _CatDetailHeaderState.build (package:catbox/ui/cat_details/header/details_header.dart:24:22)

#4      StatefulElement.build (package:flutter/src/widgets/framework.dart:4334:27)

#5      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4223:15)

#6      Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5)

...

════════════════════════════════════════════════════════════════════════════════════════════════
//Code from details_page.dart
import 'package:catbox/ui/cat_details/header/details_header.dart';
import 'package:catbox/models/cat.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

class CatDetailsPage extends StatefulWidget {
  final Cat cat;
  final Object avatarTag;

  CatDetailsPage(
      this.cat, {
        @required this.avatarTag,
      });

  @override
  _CatDetailsPageState createState() => new _CatDetailsPageState();
}

class _CatDetailsPageState extends State<CatDetailsPage> {
  @override
  Widget build(BuildContext context) {
    var linearGradient = new BoxDecoration(
      gradient: new LinearGradient(
        begin: FractionalOffset.centerRight,
        end: FractionalOffset.bottomLeft,
        colors: [
          Colors.blue,
          Colors.blue,
        ],
      ),
    );

    return new Scaffold(
      body: new SingleChildScrollView(
        child: new Container(
          decoration: linearGradient,
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children:[
              new CatDetailHeader(
                widget.cat,
                avatarTag: widget.avatarTag,
              ),
              //TODO Details Body
              //TODO Cat Showcase
            ],
          ),
        ),
      ),
    );
  }
}
//Code from detail_header.dart

import 'package:catbox/models/cat.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

class CatDetailHeader extends StatefulWidget {
  final Cat cat;
  final Object avatarTag;

  CatDetailHeader(
      this.cat, {
        @required this.avatarTag,
      });

  @override
  _CatDetailHeaderState createState() => new _CatDetailHeaderState();
}

class _CatDetailHeaderState extends State<CatDetailHeader> {
  @override
  Widget build(BuildContext context) {
    var theme = Theme.of(context);
    var textTheme = theme.textTheme;

    var avatar = new Hero(
      tag: widget.avatarTag,
      child: new CircleAvatar(
        backgroundImage: new NetworkImage(widget.cat.avatarUrl),
        radius: 75.0,
      ),
    );

    var likeInfo = new Padding(
      padding: const EdgeInsets.only(top: 16.0),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          new Icon(
            Icons.thumb_up,
            color: Colors.white,
            size: 16.0,
          ),
          new Padding(
              padding: const EdgeInsets.only(left: 8.0),
              child: new Text(
                widget.cat.likeCounter.toString(),
                style: textTheme.subhead.copyWith(color: Colors.white),
              )
          )
        ],
      ),
    );

    var actionButtons = new Padding(
      padding: const EdgeInsets.only(
        top: 16.0,
        left: 16.0,
        right: 16.0,
      ),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          new ClipRRect(
            borderRadius: new BorderRadius.circular(30.0),
            child: new MaterialButton(
              minWidth: 140.0,
              color: theme.accentColor,
              textColor: Colors.white,
              onPressed: () async {
                //TODO Handle Adopt
              },
              child: new Text('ADOPT ME'),
            ),
          ),
          new ClipRRect(
            borderRadius: new BorderRadius.circular(30.0),
            child: new RaisedButton(
              color: Colors.lightGreen,
              disabledColor: Colors.grey,
              textColor: Colors.white,
              onPressed: () async {
                //TODO Handle Like
              },
              child: new Text('LIKE'),
            ),
          ),
        ],
      ),
    );

    return new Stack(
      children: [
        //TODO Background Image
        new Align(
          alignment: FractionalOffset.bottomCenter,
          heightFactor: 1.4,
          child: new Column(
            children: [
              avatar,
              likeInfo,
              actionButtons,
            ],
          ),
        ),
        new Positioned(
          top: 26.0,
          left: 4.0,
          child: new BackButton(color: Colors.white),
        ),
      ],
    );
  }
}


1 个答案:

答案 0 :(得分:0)

您可以在下面复制粘贴运行完整代码
错误消息表示Hero标签不正确
在代码中,调用avatarTag时需要为CatDetailsPage提供一个值
ListView中,您可以将index用作标签名称的一部分,如下所示,因此它是唯一的

CatDetailsPage(cat, avatarTag: "tag${index}")

演示代码的代码段

Expanded(flex: 1,child: CatDetailsPage(cat, avatarTag: "tag")),

工作演示

enter image description here

完整代码

    import 'package:flutter/material.dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          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> {
      int _counter = 0;
      Cat cat = CatImplementation();
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Expanded(flex: 1,child: CatDetailsPage(cat, avatarTag: "tag")),
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }

    class CatDetailsPage extends StatefulWidget {
      final Cat cat;
      final Object avatarTag;

      CatDetailsPage(
        this.cat, {
        @required this.avatarTag,
      });

      @override
      _CatDetailsPageState createState() => new _CatDetailsPageState();
    }

    class _CatDetailsPageState extends State<CatDetailsPage> {
      @override
      Widget build(BuildContext context) {
        var linearGradient = new BoxDecoration(
          gradient: new LinearGradient(
            begin: FractionalOffset.centerRight,
            end: FractionalOffset.bottomLeft,
            colors: [
              Colors.blue,
              Colors.blue,
            ],
          ),
        );

        return new Scaffold(
          body: new SingleChildScrollView(
            child: new Container(
              decoration: linearGradient,
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  new CatDetailHeader(
                    widget.cat,
                    avatarTag: widget.avatarTag,
                  ),
                  //TODO Details Body
                  //TODO Cat Showcase
                ],
              ),
            ),
          ),
        );
      }
    }

    class CatDetailHeader extends StatefulWidget {
      final Cat cat;
      final Object avatarTag;

      CatDetailHeader(
        this.cat, {
        @required this.avatarTag,
      });

      @override
      _CatDetailHeaderState createState() => new _CatDetailHeaderState();
    }

    class _CatDetailHeaderState extends State<CatDetailHeader> {
      @override
      Widget build(BuildContext context) {
        var theme = Theme.of(context);
        var textTheme = theme.textTheme;

        var avatar = new Hero(
          tag: widget.avatarTag,
          child: new CircleAvatar(
            backgroundImage: new NetworkImage(widget.cat.avatarUrl),
            radius: 75.0,
          ),
        );

        var likeInfo = new Padding(
          padding: const EdgeInsets.only(top: 16.0),
          child: new Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              new Icon(
                Icons.thumb_up,
                color: Colors.white,
                size: 16.0,
              ),
              new Padding(
                  padding: const EdgeInsets.only(left: 8.0),
                  child: new Text(
                    widget.cat.likeCounter.toString(),
                    style: textTheme.subhead.copyWith(color: Colors.white),
                  ))
            ],
          ),
        );

        var actionButtons = new Padding(
          padding: const EdgeInsets.only(
            top: 16.0,
            left: 16.0,
            right: 16.0,
          ),
          child: new Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              new ClipRRect(
                borderRadius: new BorderRadius.circular(30.0),
                child: new MaterialButton(
                  minWidth: 140.0,
                  color: theme.accentColor,
                  textColor: Colors.white,
                  onPressed: () async {
                    //TODO Handle Adopt
                  },
                  child: new Text('ADOPT ME'),
                ),
              ),
              new ClipRRect(
                borderRadius: new BorderRadius.circular(30.0),
                child: new RaisedButton(
                  color: Colors.lightGreen,
                  disabledColor: Colors.grey,
                  textColor: Colors.white,
                  onPressed: () async {
                    //TODO Handle Like
                  },
                  child: new Text('LIKE'),
                ),
              ),
            ],
          ),
        );

        return new Stack(
          children: [
            //TODO Background Image
            new Align(
              alignment: FractionalOffset.bottomCenter,
              heightFactor: 1.4,
              child: new Column(
                children: [
                  avatar,
                  likeInfo,
                  actionButtons,
                ],
              ),
            ),
            new Positioned(
              top: 26.0,
              left: 4.0,
              child: new BackButton(color: Colors.white),
            ),
          ],
        );
      }
    }

    abstract class Cat {
      String get avatarUrl;
      int get likeCounter;
    }

    class CatImplementation extends Cat {
      String avatarUrl = "https://i.pravatar.cc/150?img=1";
      int likeCounter = 0;
    }