我收到此错误:
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()),
]),
),
),
],
)),
答案 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
中提供固定大小。逻辑错误。如果删除图标大小或展开,此问题将得到修复。