使用TextField会引发“未找到材料小部件”错误

时间:2020-02-07 14:21:36

标签: 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)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

3 个答案:

答案 0 :(得分:1)

让我们阅读错误消息:TextField widgets require a Material widget ancestor.,这表明您从List<Widget> _buildList()来的TextField小部件渲染缺少Material小部件祖先,这意味着您的父方法需要MaterialApp和{ {1}}(通常)。

Perhaps this existing question/answer may help you.

答案 1 :(得分:0)

我有一个类似的错误,只是它是由 ListTile小部件产生的,并且它说构建ListTile(dirty)时引发了以下断言: 找不到材料小部件。 ListTile小部件需要Material小部件祖先。 ... ,解决方案是, 要引入“材质”小部件,您可以直接包含其中一个,也可以使用包含材质本身的小部件,例如Card,Dialog,Drawer, 因此,如果在使用Card,Dialog,Drawer或Scaffold作为窗口小部件树的父级后您的应用程序崩溃,则包装整个窗口小部件树使用材质小部件,该异常将消失。

答案 2 :(得分:0)

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

相关问题