【问题标题】:Using TextField throws “No Material widget found” error使用 TextField 会引发“未找到材料小部件”错误
【发布时间】:2020-05-23 16:45:26
【问题描述】:

大家好,我是 Flutter 的新手,我正在尝试制作一个菜单,您可以在其中添加和删除一些玩家。问题是我得到一个“没有找到材料小部件”。错误。我究竟做错了什么 ?谢谢你。

_______________________________________________________________________________

代码:

import 'package:flutter/material.dart';

class PlayerList extends StatefulWidget {


  const PlayerList({
    this.initialCount = 5,
  });

  // also allow for a dynamic number of starting players
  final int initialCount;

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

class _PlayerListState extends State<PlayerList> {
  int fieldCount = 0;
  int nextIndex = 0;

  // you must keep track of the TextEditingControllers if you want the values to persist correctly
  List<TextEditingController> controllers = <TextEditingController>[];

  // create the list of TextFields, based off the list of TextControllers
  List<Widget> _buildList() {
    int i;
    // fill in keys if the list is not long enough (in case we added one)
    if (controllers.length < fieldCount) {
      for (i = controllers.length; i < fieldCount; i++) {
        controllers.add(TextEditingController());
      }
    }

    i = 0;
    // cycle through the controllers, and recreate each, one per available controller
    return controllers.map<Widget>((TextEditingController controller) {
      int displayNumber = i + 1;
      i++;

      return TextField(
          controller: controller,
          maxLength: 20,
          decoration: InputDecoration(
          labelText: "Player $displayNumber",
          counterText: "",
          prefixIcon: const Icon(Icons.person),
          suffixIcon: IconButton(
            icon: Icon(Icons.clear),
            onPressed: () {
              // when removing a TextField, you must do two things:
              // 1. decrement the number of controllers you should have (fieldCount)
              // 2. actually remove this field's controller from the list of controllers
              setState(() {
                fieldCount--;
                controllers.remove(controller);
              });
            },
          ),
          ),
      );
    }).toList(); // convert to a list
  }


  @override
  Widget build(BuildContext context) {

    // generate the list of TextFields
    final List<Widget> children = _buildList();


    // append an 'add player' button to the end of the list
    children.add(
      GestureDetector(
        onTap: () {
          // when adding a player, we only need to inc the fieldCount, because the _buildList()
          // will handle the creation of the new TextEditingController
          setState(() {
            fieldCount++;
          });
        },
        child: Container(
          color: Colors.blue,
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Text(
              'Spieler hinzufügen',
              style: TextStyle(
                color: Colors.white,
              ),
            ),
          ),
        ),
      ),

    );

    // build the ListView
    return ListView(
      padding: EdgeInsets.all(0),
      shrinkWrap: true,
      physics: NeverScrollableScrollPhysics(),
      children: children,

    );
  }


  @override
  void initState() {
    super.initState();

    // upon creation, copy the starting count to the current count
    fieldCount = widget.initialCount;
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void didUpdateWidget(PlayerList oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }
}

_______________________________________________________________________________

这是错误堆栈:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building TextField(controller: TextEditingController#ecada(TextEditingValue(text: ┤├, selection: TextSelection(baseOffset: -1, extentOffset: -1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))), decoration: InputDecoration(labelText: "Player 1", prefixIcon: Icon(IconData(U+0E7FD)), suffixIcon: IconButton(Icon, padding: EdgeInsets.all(8.0)), counterText: ), maxLength: 20, dirty, state: _TextFieldState#edbe3):
No Material widget found.

TextField 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: TextField
  controller: TextEditingController#ecada(TextEditingValue(text: ┤├, selection: TextSelection(baseOffset: -1, extentOffset: -1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1)))
  decoration: InputDecoration(labelText: "Player 1", prefixIcon: Icon(IconData(U+0E7FD)), suffixIcon: IconButton(Icon, padding: EdgeInsets.all(8.0)), counterText: )
  maxLength: 20
  dirty
  state: _TextFieldState#edbe3
The ancestors of this widget were: 
  : ListView
    scrollDirection: vertical
    primary: using primary controller
    NeverScrollableScrollPhysics
    shrinkWrap: shrink-wrapping
    padding: EdgeInsets.zero
  : PlayerList
    state: _PlayerListState#89cb2
  : MaterialApp
    state: _MaterialAppState#2ca5b
  : MyApp
  ...
The relevant error-causing widget was: 
  TextField file:///C:/Flutter%20Project/flutter_app/flutter_app/lib/Pages/HomeTrinkspiel.dart:184:14
When the exception was thrown, this was the stack: 
#0      debugCheckHasMaterial.<anonymous closure> (package:flutter/src/material/debug.dart:28:7)
#1      debugCheckHasMaterial (package:flutter/src/material/debug.dart:50:4)
#2      _TextFieldState.build (package:flutter/src/material/text_field.dart:898:12)
#3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4334:27)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4223:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

【问题讨论】:

标签: flutter


【解决方案1】:

让我们阅读一下错误消息:TextField widgets require a Material widget ancestor. 这表明从 List&lt;Widget&gt; _buildList() 渲染的 TextField 小部件缺少 Material 小部件祖先,这意味着您的父方法需要 MaterialAppScaffold(通常)。

Perhaps this existing question/answer may help you.

【讨论】:

    【解决方案2】:

    我遇到了类似的错误,除了它是由 ListTile 小部件 生成的,并且它说 在构建 ListTile(dirty) 时抛出了以下断言: 未找到材质小部件。 ListTile 小部件需要一个 Material 小部件祖先。 ... 解决方案是这样的,要引入 Material 小部件,您可以直接包含一个,也可以使用包含 Material 本身的小部件,例如 Card、Dialog、Drawer、或 Scaffold。因此,如果您的应用在使用 Card、Dialog、Drawer 或 Scaffold 作为小部件树的父级后崩溃,则包装整个小部件树使用材质小部件,异常将消失。

    【讨论】:

      【解决方案3】:

      要引入 Material 小部件,您可以直接包含一个,也可以使用包含 Material 本身的小部件,例如 Card()Dialog()抽屉,或Scaffold()

      【讨论】:

        猜你喜欢
        • 2021-12-18
        • 1970-01-01
        • 2017-10-12
        • 2020-08-18
        • 2022-08-18
        • 2019-01-17
        • 2021-05-18
        • 1970-01-01
        相关资源
        最近更新 更多