【问题标题】:Flutter -Temporary error - IconButton widgets require a Material widget ancestorFlutter - 临时错误 - IconButton 小部件需要 Material 小部件祖先
【发布时间】:2021-02-24 03:35:57
【问题描述】:

我收到此错误:

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()),
                                      ]),
                                ),
                              ),
                            ],
                          )),

【问题讨论】:

  • 这能回答你的问题吗? No Material widget found
  • @hasankaraman 不,不幸的是,它已经在 Scaffold 内的 LoggedOutEmailView 小部件内,并且错误只是一秒钟。干杯

标签: flutter flutter-layout


【解决方案1】:

由于您将VpBackButton 灵活包装在LoggedOutEmailView 中,因此您无法在VpBackButton 中提供固定大小。逻辑错误。如果您删除图标大小或展开,它是固定的。

【讨论】:

    【解决方案2】:

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

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

    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())),
    

    【讨论】:

      猜你喜欢
      • 2019-03-26
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2018-11-06
      • 1970-01-01
      • 2022-11-19
      • 2021-03-31
      相关资源
      最近更新 更多