我正在构建一个Flutter应用程序,我需要将功能传递给其他小部件。
我有这8个TextFormFields及其值。
当我按下灰色按钮“Smazat hodnotypasažérů”时,它应该清除所有文本字段。
我在一个文件pasazeri.dart中有文本字段,在另一个文件deleteBtn.dart中有按钮。
我想我可以将清除框的功能发送给我的按钮小部件,但它不起作用。
这是我的pasazeri.dart的完整代码
import 'package:flutter/services.dart';
import 'deleteBtn.dart';
class Pasazeri extends StatefulWidget {
@override
_PasazeriState createState() => _PasazeriState();
}
class _PasazeriState extends State<Pasazeri> {
final FocusNode pasazer1 = FocusNode();
final FocusNode pasazer2 = FocusNode();
final FocusNode pasazer3 = FocusNode();
final FocusNode pasazer4 = FocusNode();
final FocusNode pasazer5 = FocusNode();
final FocusNode pasazer6 = FocusNode();
final FocusNode pasazer7 = FocusNode();
final FocusNode pasazer8 = FocusNode();
TextEditingController contPasazer1 = TextEditingController();
TextEditingController contPasazer2 = TextEditingController();
TextEditingController contPasazer3 = TextEditingController();
TextEditingController contPasazer4 = TextEditingController();
TextEditingController contPasazer5 = TextEditingController();
TextEditingController contPasazer6 = TextEditingController();
TextEditingController contPasazer7 = TextEditingController();
TextEditingController contPasazer8 = TextEditingController();
_fieldFocusChange(
BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
currentFocus.unfocus();
FocusScope.of(context).requestFocus(nextFocus);
}
void clearBoxes() {
setState(() {
contPasazer1.clear();
contPasazer2.clear();
contPasazer3.clear();
contPasazer4.clear();
contPasazer5.clear();
contPasazer6.clear();
contPasazer7.clear();
contPasazer8.clear();
});
}
Widget pasazer(cisloPasazer, controller, focusnode, next) {
return Container(
margin: EdgeInsets.only(left: 8),
child: Row(
children: <Widget>[
Text(
"$cisloPasazer. pasažér: ",
style: TextStyle(fontSize: 14.5, fontWeight: FontWeight.w500),
),
Container(
padding: EdgeInsets.only(left: 3),
width: 40,
height: 25,
decoration: BoxDecoration(
color: Color(0xFFFFDD80),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Center(
child: TextFormField(
controller: controller,
focusNode: focusnode,
textInputAction: TextInputAction.next,
onChanged: (String str) => DeleteBtn(delete: clearBoxes),
onFieldSubmitted: (term) {
_fieldFocusChange(context, focusnode, next);
},
style: TextStyle(
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.w600),
cursorWidth: 1,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 9),
border: InputBorder.none,
hintText: "",
hintStyle: TextStyle(
color: Color(0xFF9c9a98),
),
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(3),
],
),
),
),
Text(" kg",
style: TextStyle(fontSize: 14.5, fontWeight: FontWeight.w500))
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(
top: MediaQuery.of(context).size.height * 0.015,
bottom: MediaQuery.of(context).size.height * 0.015,
left: 8,
right: 8),
padding: EdgeInsets.symmetric(
vertical: MediaQuery.of(context).size.height * 0.012),
decoration: BoxDecoration(
color: Color(0xFFa38b5f),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
pasazer(1, contPasazer1, pasazer1, pasazer2),
Container(
margin: EdgeInsets.only(right: 8),
child: Row(
children: <Widget>[
pasazer(5, contPasazer5, pasazer5, pasazer6),
],
),
)
],
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
pasazer(2, contPasazer2, pasazer2, pasazer3),
Container(
margin: EdgeInsets.only(right: 8),
child: Row(
children: <Widget>[
pasazer(6, contPasazer6, pasazer6, pasazer7),
],
),
)
],
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
pasazer(3, contPasazer3, pasazer3, pasazer4),
Container(
margin: EdgeInsets.only(right: 8),
child: Row(
children: <Widget>[
pasazer(7, contPasazer7, pasazer7, pasazer8),
],
),
)
],
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
pasazer(4, contPasazer4, pasazer4, pasazer5),
Container(
margin: EdgeInsets.only(right: 8),
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 8),
child: Row(
children: <Widget>[
Text(
"8. pasažér: ",
style: TextStyle(
fontSize: 14.5, fontWeight: FontWeight.w500),
),
Container(
padding: EdgeInsets.only(left: 3),
width: 40,
height: 25,
decoration: BoxDecoration(
color: Color(0xFFFFDD80),
borderRadius:
BorderRadius.all(Radius.circular(10))),
child: Center(
child: TextFormField(
controller: contPasazer8,
focusNode: pasazer8,
textInputAction: TextInputAction.done,
onFieldSubmitted: (term) {
pasazer8.unfocus();
},
style: TextStyle(
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.w600),
cursorWidth: 1,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
contentPadding:
EdgeInsets.symmetric(vertical: 9),
border: InputBorder.none,
hintText: "",
hintStyle: TextStyle(
color: Color(0xFF9c9a98),
),
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(3),
],
onChanged: (String str) {},
),
),
),
Text(" kg",
style: TextStyle(
fontSize: 14.5,
fontWeight: FontWeight.w500))
],
),
),
],
),
)
],
),
),
],
),
);
}
}
这是我的deleteBtn.dart代码
class DeleteBtn extends StatelessWidget {
final Function delete;
DeleteBtn({this.delete});
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
height: 40,
margin: EdgeInsets.only(right: 8),
decoration: BoxDecoration(
color: Color(0xFF616161),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: FlatButton(
padding: EdgeInsets.symmetric(horizontal: 0),
child: Text(
"Smazat hodnoty pasažérů",
style: TextStyle(fontSize: 10),
),
onPressed: () {
print(delete);
delete();
},
),
),
);
}
}
当我按下按钮时,我需要调用pasazeri.dart中的clearBoxes()
函数我在
print(delete);
中添加了onPressed:
,它给了我:The following NoSuchMethodError was thrown while handling a gesture:
The method 'call' was called on null.
Receiver: null
Tried calling: call()
所以我认为传递函数存在问题。有谁知道我该如何解决?
最佳答案
您的代码中存在某些问题,这些问题无法实现。我会为您指出:
setState()
中执行clearBoxes()
,因为这样做就可以了。当变量的setState
的value
发生更改时,使用state
反射(reflect)在小部件中。例如:在按钮上单击+1
或更具体地说,添加Counter
,向 Controller setState(() => contPasazer1.text = "New value")
function
传递到窗口小部件,您应该执行delete: () => your_function_name
,而不是 delete: clearBoxes
。您的删除是void
类型,它是dart formatting error
。因此,即使您通过了正确的方法让我们看一下上面实例的更正代码:
void clearBoxed(){
// no need of setState
contPasazer1.clear();
contPasazer2.clear();
contPasazer3.clear();
contPasazer4.clear();
contPasazer5.clear();
contPasazer6.clear();
contPasazer7.clear();
contPasazer8.clear();
}
正确将clearBoxes()
传递给DeleteBtn
类参数delete
。阅读Pass function into a function in Dart// you can also do this (){ clearBoxes() }, but below is more dart way or JS way
onChanged: (String str) => DeleteBtn(delete: () => clearBoxes())
另外,我想知道为什么在DeleteBtn()
中使用onChanged()
?如果您想将其用作按钮,只需将其放置在此处,然后使用该按钮对于更简洁的方法,您可以在开始键入类似以下内容时调用
clearBoxes()
方法:onChanged: (String str) => clearBoxes()
无论您想在何处使用按钮,都可以通过放置DeleteBtn
来使用它,如下所示:Row(
children: [
TextFormField(
onChanged: (String str) => clearBoxes()
),
DeleteBtn(delete: () => clearBoxes())
]
)
考虑使用最佳实践,从长远来看,它将为您提供帮助。我正在显示我的代码以显示事情是如何工作的。 我刚刚使用了3个TexField和一个DeleteBtn来显示的工作原理。
关注代码中的工作方式,特别是
clearBoxes()
和DeleteBtn(delete: () => clearBoxes())
class _MyHomePageState extends State<MyHomePage> {
TextEditingController contPasazer1 = TextEditingController();
TextEditingController contPasazer2 = TextEditingController();
TextEditingController contPasazer3 = TextEditingController();
// no need of setState()
void clearBoxes() {
contPasazer1.clear();
contPasazer2.clear();
contPasazer3.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: double.infinity,
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(controller: contPasazer1),
SizedBox(height: 20.0),
TextFormField(controller: contPasazer2),
SizedBox(height: 20.0),
TextFormField(controller: contPasazer3),
SizedBox(height: 20.0),
// Your delete button from another class
DeleteBtn(delete: () => clearBoxes())
]
)
)
);
}
}
// Your other class
class DeleteBtn extends StatelessWidget {
final Function delete;
DeleteBtn({this.delete});
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
height: 40,
margin: EdgeInsets.only(right: 8),
decoration: BoxDecoration(
color: Color(0xFF616161),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: FlatButton(
padding: EdgeInsets.symmetric(horizontal: 0),
child: Text(
"Smazat hodnoty pasažérů",
style: TextStyle(fontSize: 10),
),
onPressed: () {
print(delete);
delete();
},
),
),
);
}
}
结果免责声明:不要看UI,我要请您看一下功能。我仅使用了
DeleteBtn
,但布局不理想,因此深表歉意。关于flutter - 如何在两个小部件(文件)之间传递数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63159092/