我在 Flutter 中遇到了一个问题:在构建 TextField 时抛出了以下断言,它使我遇到了一个奇怪的问题
Posted
技术标签:
【中文标题】我在 Flutter 中遇到了一个问题:在构建 TextField 时抛出了以下断言,它使我遇到了一个奇怪的问题【英文标题】:I got stuck with a problem in Flutter: The following assertion was thrown building TextField, it flesh me a stranger problem 【发布时间】:2019-05-15 02:23:21 【问题描述】:我在 Flutter 中遇到了一个问题:在构建 TextField 时抛出了以下断言,这让我在短时间内遇到了一个奇怪的问题!
对于代码或错误的任何澄清,请在下面评论,我会在几分钟内回复,因为我迫不及待地想解决这个问题并没有太多想法继续前进!!
我是一个非常接近 Flutter 编程的意大利男孩,我从这门课程开始。你是我唯一可以称呼的人。我会为任何能解决这个“问题”的人提供玛格丽塔披萨;)!!!
Andoid Studio返回给我的错误是这样的:
I/flutter (26182):以下断言被抛出构建 TextField(控制器:I/flutter(26182): TextEditingController#e1688(TextEditingValue(文本:┤├,选择: TextSelection(baseOffset: -1, I/flutter (26182): extentOffset: -1, 亲和力:TextAffinity.downstream,isDirectional:false),组成: 我/颤振(26182):TextRange(开始:-1,结束:-1))),启用:真, 装饰: InputDecoration(hintText: "Materia"), I/flutter (26182): 自动更正:true,强制执行最大长度,onTap:空,脏,状态: _TextFieldState#73fdb):I/flutter (26182):未找到材质小部件。 I/flutter (26182):TextField 小部件需要一个 Material 小部件 祖先。 I/flutter (26182):在材料设计中,大多数小部件都是 概念上“印刷”在一张材料上。在 Flutter 的 I/flutter 中 (26182):材料库,该材料由 材质小部件。它是 Material 小部件 I/flutter (26182): 例如,呈现墨水飞溅。正因为如此,许多材料 库小部件需要 I/flutter (26182):有一个 Material 它们上方的树中的小部件。 I/flutter (26182):引入一个 Material 小部件,您可以直接包含一个,也可以使用一个小部件 包含 I/flutter (26182):材质本身,例如卡片, 对话框、抽屉或脚手架。 I/flutter (26182):特定的小部件 找不到 Material 祖先的是:I/flutter (26182): 文本字段(控制器: TextEditingController#e1688(TextEditingValue(文本:┤├,选择: I/颤振(26182):TextSelection(baseOffset:-1,extentOffset:-1, 亲和力:TextAffinity.downstream,isDirectional:I/flutter (26182): 假),组成:TextRange(开始:-1,结束:-1))),启用:真, 装饰:I/flutter (26182): InputDecoration(hintText: "Materia"), 自动更正:true,强制执行最大长度,onTap:null)I/flutter (26182):这个小部件的祖先是:
...还有一长串小部件
这是我的代码,一个非常简单的输入表单,包含 2 个表单,“材料”和“描述”以及将其加载到名为“AssegnoPage”的 TabBarView 的页面。我使用范围模型,您会在下面找到它。 u
关注AssegnoPage的标签:AssegnoListPage和AggiungiAssegno
AssegnoPage:
import 'package:flutter/material.dart';
import 'package:prova_app_book/assegno/page/aggiungi_assegno.dart'; import 'package:prova_app_book/widget/drawer.dart'; import 'assegno_list.dart'; //import '../../models/assegno.dart';
class AssegnoPage extends StatelessWidget
@override Widget build(BuildContext context)
return DefaultTabController(
length: 2,
child: Scaffold(
drawer: Drawer(child: DrawerWidget(),),
appBar: AppBar(
title: Text('Gestione Assegno'),
bottom: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.edit),
text: 'Aggiungi Assegno',
),
Tab(
icon: Icon(Icons.book),
text: 'Il tuo assegno',
),
],
),
),
body: TabBarView(children: <Widget> [
AggiungiAssegno(),
AssegnoListPage()
]),
),
);
最后带有提交按钮的简单表单:
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import '../../scoped_models/assegno.dart';
import '../../models/assegno.dart';
class AggiungiAssegno extends StatefulWidget
@override
State<StatefulWidget> createState()
return _AggiungiAssegnoState();
class _AggiungiAssegnoState extends State<AggiungiAssegno>
final Map<String, dynamic> _formData =
'materia': null,
'assegno': null,
;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
Widget _buildTitoloMateria(Assegno assegno)
return TextFormField(
decoration: InputDecoration(hintText: 'Materia'),
initialValue: assegno == null ? '' : assegno.materia,
validator: (String value)
if (value.isEmpty)
return 'Il nome della materia è necessario';
,
onSaved: (String value)
_formData['materia'] = value;
,
);
Widget _buildAssegno(Assegno assegno)
return TextFormField(
decoration: InputDecoration(hintText: 'Assegno'),
maxLines: 3,
initialValue: assegno == null ? '' : assegno.assegno,
validator: (String value)
if (value.isEmpty)
return 'L\'assegno è necessario';
,
onSaved: (String value)
_formData['assegno'] = value;
,
);
void _submitForm(Function aggiungiAssegno, Function aggiornaAssegno, [int selectedAssegnoIndex])
if (!_formKey.currentState.validate())
return;
_formKey.currentState.save();
if (selectedAssegnoIndex == null)
aggiungiAssegno(Assegno(
materia: _formData['materia'], assegno: _formData['assegno']));
else
aggiornaAssegno(
Assegno(
materia: _formData['materia'], assegno: _formData['assegno']));
Navigator.pushReplacementNamed(context, '/panoramica');
Widget _buildSubmitButton()
return ScopedModelDescendant<AssegnoModel>(
builder: (BuildContext context, Widget child, AssegnoModel model)
return RaisedButton(
child: Text('Fatto'),
textColor: Colors.white,
onPressed: () =>
_submitForm(model.aggiungiAssegno, model.aggiornaAssegno, model.selectesAssegnoIndex),
);
,
);
Widget _buildPageContent(BuildContext context, Assegno assegno)
final double deviceWidth = MediaQuery.of(context).size.width;
final double targetWidth = deviceWidth > 550.0 ? 500.0 : deviceWidth * 0.95;
final double targetPadding = deviceWidth - targetWidth;
return Container(
margin: EdgeInsets.all(10.0),
child: Form(
key: _formKey,
child: ListView(
padding: EdgeInsets.symmetric(horizontal: targetPadding / 2),
children: <Widget>[
_buildTitoloMateria(assegno),
SizedBox(
height: 20.0,
),
_buildAssegno(assegno),
SizedBox(
height: 20.0,
),
_buildSubmitButton(),
],
),
),
);
@override
Widget build(BuildContext context)
return ScopedModelDescendant<AssegnoModel>(
builder: (BuildContext context, Widget child, AssegnoModel model)
final Widget pageContent = _buildPageContent(context, model.selectedAssegno);
return model.selectesAssegnoIndex == null
? pageContent
: Scaffold(
appBar: AppBar(
title: Text('Aggiungi Assegno'),
),
body: pageContent,
);
,
);
AssegnoListPage,这里,我返回上一页,按下按钮,flutter给我上面的错误!:
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
//import '../../models/assegno.dart';
import 'aggiungi_assegno.dart';
import '../../scoped_models/assegno.dart';
class AssegnoListPage extends StatelessWidget
@override
Widget build(BuildContext context)
return ScopedModelDescendant<AssegnoModel>(
builder: (BuildContext context, Widget child, AssegnoModel model)
return ListView.builder(
itemBuilder: (BuildContext context, int index)
return Column(
children: <Widget>[
ListTile(
leading: Icon(Icons.book),
title: Text(model.assegno[index].materia),
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: ()
model.selectAssegno(index);
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context)
return AggiungiAssegno();
,
),
);
),
),
Divider(),
],
);
,
itemCount: model.assegno.length,
);
,
);
表格中使用的范围模型:
import 'package:scoped_model/scoped_model.dart';
import '../models/assegno.dart';
class AssegnoModel extends Model
List <Assegno> _assegno = [];
int _selectesAssegnoIndex;
List<Assegno> get assegno
return List.from(_assegno);
int get selectesAssegnoIndex
return _selectesAssegnoIndex;
Assegno get selectedAssegno
if(_selectesAssegnoIndex == null)
return null;
return _assegno[_selectesAssegnoIndex];
void aggiungiAssegno(Assegno assegno)
_assegno.add(assegno);
_selectesAssegnoIndex = null;
//print(_assegno);
void aggiornaAssegno(Assegno assegno)
_assegno[_selectesAssegnoIndex] = assegno;
_selectesAssegnoIndex = null;
void eliminaAssegno()
_assegno.removeAt(_selectesAssegnoIndex);
_selectesAssegnoIndex = null;
void selectAssegno(int index)
_selectesAssegnoIndex = index;
【问题讨论】:
我不相信这应该有 [java] 标签,Sabatin。 Flutter 使用了 Dart,这就是您在此处包含的所有内容。 【参考方案1】:异常解释了发生了什么:
TextField 小部件需要 Material 小部件祖先。
要引入这样的Material
小部件,您有多种可能:
例子:
Material(
child: TextField(...),
)
【讨论】:
我编辑了问题:我添加了 AssegnoPage 页面以更好地理解代码,并希望有人能帮助我解决问题,因为有一个小部件祖先,但代码没有无论如何都行不通!抱歉,如果我回复晚了,但我们有不同的时区。请重新检查代码。【参考方案2】:您必须将 TextFormField 包含在 Form 小部件中,以便使用 validate () 方法和 save () 方法将 TextFormField 的值保存在 String 变量中。这里我留下一个出现在 Flutter 文档中的示例 => Example Forms
【讨论】:
以上是关于我在 Flutter 中遇到了一个问题:在构建 TextField 时抛出了以下断言,它使我遇到了一个奇怪的问题的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在构建项目时出现 Flutter gradle 错误?
Flutter 构建 apk:在模块 guava-26.0-android.jar 和 listenablefuture-1.0.jar 中发现了重复的类
添加 firebase 后构建 Flutter apk 时出现 Gradle 错误