Flutter-临时错误-IconButton小部件需要Material小部件祖先

时间:2020-11-12 06:03:26

标签: flutter flutter-layout

我收到此错误:

IconButton小部件需要Material小部件祖先

大约一秒钟,然后消失。它抱怨我的一个自定义小部件中有一个IconButton。但是,自定义窗口小部件放置在带有Scaffold的页面中。因此,该错误不应存在,因为自定义按钮位于Scaffold材质小部件内。当我将按钮的用法包装在它自己的小Scaffold中时,所有问题都解决了。为什么我会暂时出现此错误?是否将自定义窗口小部件包装在很小的Scaffold中被视为是黑客修复还是实际修复?所有代码和完整错误如下:

错误:

The following assertion was thrown building IconButton(Icon, padding: EdgeInsets.zero, dirty):
No Material widget found.

IconButton widgets require a Material widget ancestor.
In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter's material library, that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. Because of this, many material library widgets require that there be a Material widget in the tree above them.

To introduce a Material widget, you can either directly include one, or use a widget that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

The specific widget that could not find a Material ancestor was: IconButton
    Icon
    padding: EdgeInsets.zero
    dirty
The ancestors of this widget were
    VpBackButton
    Align
        alignment: centerLeft
        dependencies: [Directionality]
        renderObject: RenderPositionedBox#49b68 NEEDS-LAYOUT NEEDS-PAINT
    Expanded
        flex: 1
    Row
        direction: horizontal
        mainAxisAlignment: center
        crossAxisAlignment: center
        textBaseline: alphabetic
        dependencies: [Directionality]
        renderObject: RenderFlex#19d87 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    GetMaterialApp
    App
    ...
The relevant error-causing widget was
IconButton
lib/…/back_button/back_button_widget.dart:18
When the exception was thrown, this was the stack
#0      debugCheckHasMaterial.<anonymous closure>
package:flutter/…/material/debug.dart:30
#1      debugCheckHasMaterial
package:flutter/…/material/debug.dart:52
#2      IconButton.build
package:flutter/…/material/icon_button.dart:330
#3      StatelessElement.build
package:flutter/…/widgets/framework.dart:4701
#4      ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4627
...
════════════════════════════════════════════════════════════════════════════════

它在抱怨我的自定义小部件:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vepo/presentation/modules/view.dart';

import 'back_button_widget_controller.dart';

class VpBackButton extends VpView<VpBackButtonController> {
  VpBackButton({this.onPressed}) {
    Get.put(VpBackButtonController());
  }

  @required
  final VoidCallback onPressed;
  AnimationController animateController;

  @override
  Widget build(BuildContext context) {
    return IconButton(
      padding: const EdgeInsets.all(0.0),
      icon: Icon(Icons.arrow_back_ios_rounded,
          color: Colors.white.withOpacity(0.5)),
      iconSize: 38,
      onPressed: () {
        controller.goBack(onPressed);
      },
    );
  }
}

该按钮位于其中的页面包含一个Scaffold,它是一个材质小部件:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:vepo/presentation/themes/home_theme.dart';
import 'package:vepo/presentation/widgets/display/buttons/back_button/back_button_widget.dart';
import 'package:vepo/presentation/widgets/display/buttons/elevated_buttons/elevated_submit_button_widget.dart';
import 'package:vepo/presentation/widgets/display/containers/gradient_container_widget.dart';
import 'package:vepo/presentation/widgets/display/text/subtitle_1_widget.dart';
import 'package:vepo/presentation/widgets/forms/text_field/text_field_widget.dart';
import 'package:vepo/presentation/widgets/pages/gradient_page_scaffold_widget.dart';

import '../../../../assets.gen.dart';
import 'logged_out_email_controller.dart';

class LoggedOutEmailView extends GetView<LoggedOutEmailController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomPadding: false,
        body: ConstrainedBox(
            constraints: BoxConstraints.tightFor(
                height: MediaQuery.of(context).size.height),
            child: VpGradientContainer(
                beginColor: initialGradientColor,
                endColor: endGradientColor,
                child: SafeArea(
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                      Expanded(
                          flex: 1,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Expanded(
                                flex: 1,
                                child: Hero(
                                  tag: 'logoHero',
                                  child: Row(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.center,
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Expanded(
                                            flex: 1,
                                            child: Align(
                                                alignment: Alignment.centerLeft,
                                                child: VpBackButton())),
                                        Expanded(
                                            flex: 1,
                                            child: Assets.images.logo.image()),
                                        Expanded(flex: 1, child: Container()),
                                      ]),
                                ),
                              ),
                            ],
                          )),

2 个答案:

答案 0 :(得分:1)

您看到的问题是 Flutter 中的 known bug 涉及 Hero 动画。

在您的情况下,我看到 VpBackButton 位于 Hero 之下。如果删除 Hero,您会看到错误消失了。根据上面链接的错误,目前只有一种解决方法,您已经自己发现了,它是用 Hero 包裹 VpBackButton 的内容,在您的情况下为 Material }} 小部件。

child: Hero(
    tag: 'logoHero',
    child: Row( <--- wrap this with Material widget***************
        crossAxisAlignment:
            CrossAxisAlignment.center,
        mainAxisAlignment:
            MainAxisAlignment.center,
        children: [
        Expanded(
            flex: 1,
            child: Align(
                alignment: Alignment.centerLeft,
                child: VpBackButton())),

答案 1 :(得分:0)

由于您将VpBackButton灵活地包装在LoggedOutEmailView中,因此无法在VpBackButton中提供固定大小。逻辑错误。如果删除图标大小或展开,此问题将得到修复。