我嘗試將 TextEditingController 從父類傳遞給子類。我不知道,該怎么做。
這是我的課程,我想在其中使用我想作為引數給出的 TextEditingController。
class AutocompleteField extends StatelessWidget {
const AutocompleteField({Key? key}) : super(key: key);
static const List<String> _kOptions = <String>[
'Superdry',
'A&F',
'H&M',
];
Widget build(BuildContext context) {
return Autocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _kOptions.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder: (BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (str) => onFieldSubmitted(),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
contentPadding: EdgeInsets.only(left: 12.0),
));
},
onSelected: (String selection) {
debugPrint('You just selected $selection');
},
);
}
}
我這樣在父類中呼叫它。
Padding(
padding: const EdgeInsets.only(left: 12.0, top: 12.0),
child: Text(
"Marke",
style: TextStyle(
color: Colors.grey[800],
),
)),
AutocompleteField(labelTextController),
labelTextController 是我在父類中定義的 TextEditingController 并希望在 AutoComplete 小部件的類中呼叫以更新狀態。你有什么建議嗎?
非常感謝!
uj5u.com熱心網友回復:
我認為這里真正的挑戰是如何使用控制器,而不是簡單地在父母和孩子之間傳遞它。這是一個非常有趣的問題。您基本上需要將控制器從子級提升到其父級,而不是反過來。也就是說,fieldViewBuilder已經創建了一個控制器供您使用。這是一個實作嘗試:
1. 家長:
父級必須是狀態感知小部件。為了簡單起見,我們將StatefullWidget在這里簡單地進行。但是您可以使用其他狀態管理策略來獲得更集中的解決方案。有關更多詳細資訊,請參閱代碼中的注釋。
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
@override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
// This is the controller that will help us update the child's text filed
late TextEditingController _controller;
@override
Widget build(BuildContext context) {
return ListView(
children: [
// This button is here just for testing that we are, indeed,
// updating the textFiled with whatever value we pass to the
// controller
ElevatedButton(
onPressed: () {
_controller.text = 'Hello World';
},
child: const Text("Updated Text")),
// Here we call the child's builder function to get a reference
// to the textEditingController. Check section 2 (the Child) for
// more details
AutocompleteField(
builder: (TextEditingController ctrlr) {
_controller = ctrlr;
},
),
],
);
}
}
2. 孩子
孩子已經定義了一個TextEditingController我們只需要提升它對父母的參考。我們通過創建一個builder函式來做到這一點。再次,查看評論以獲取更多詳細資訊。
您可以隨意呼叫此函式。我只是
builder通過反射選擇了:s
class AutocompleteField extends StatelessWidget {
// Here we define the builder that will lift the TextEditingController
// up to the parent
final Function(TextEditingController)? builder;
const AutocompleteField({
this.builder,
Key? key,
}) : super(key: key);
static const List<String> _kOptions = <String>[
'Superdry',
'A&F',
'H&M',
'Hello',
'World',
];
@override
Widget build(BuildContext context) {
return Autocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _kOptions.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder: (
BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted,
) {
// If the builder is defined, we use it here to get a reference
// to the textEditingController defined in the fieldViewBuilder
if (builder != null) {
builder!(textEditingController);
}
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (str) => onFieldSubmitted(),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
contentPadding: EdgeInsets.only(left: 12.0),
),
);
},
onSelected: (String selection) {
debugPrint('You just selected $selection');
},
);
}
}
干杯
uj5u.com熱心網友回復:
您必須在 AutocompleteField 類中宣告文本編輯控制器,如下所示
class AutocompleteField extends StatelessWidget {
final TextEditingController labelTextController;
const AutocompleteField({required this.labelTextController, Key? key})
: super(key: key);
static const List<String> _kOptions = <String>[
'Superdry',
'A&F',
'H&M',
];
Widget build(BuildContext context) {
return Autocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _kOptions.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder: (BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (str) => onFieldSubmitted(),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
contentPadding: EdgeInsets.only(left: 12.0),
));
},
onSelected: (String selection) {
debugPrint('You just selected $selection');
},
);
}
}
并且您可以傳遞您的控制器,如下所示
AutocompleteField(
labelTextController: labelTextController,
);
uj5u.com熱心網友回復:
您必須按照以下步驟將控制器從父類傳遞給子類:-
首先將這樣的一個引數添加到子類中
class `AutocompleteField` extends StatelessWidget {
final TextEditingController labelTextController;
const AutocompleteField({required this.labelTextController, Key? key})
: super(key: key);
static const List<String> _kOptions = <String>[
'Superdry',
'A&F',
'H&M',
];
Widget build(BuildContext context) {
return Autocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _kOptions.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
fieldViewBuilder: (BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted) {
return TextFormField(
controller: textEditingController,
focusNode: focusNode,
onFieldSubmitted: (str) => onFieldSubmitted(),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
contentPadding: EdgeInsets.only(left: 12.0),
));
},
onSelected: (String selection) {
debugPrint('You just selected $selection');
},
);
}
}
然后在呼叫時傳遞控制器。
AutocompleteField(controllername);
uj5u.com熱心網友回復:
您的 AutocompleteField 應該看起來像這樣
class AutoCompleteField extends StatefulWidget {
const AutoCompleteField({Key? key, required this.textEditingController}) : super(key: key);
final TextEditingController textEditingController; // declare a variable as parameter for the class
@override
State<AutoCompleteField> createState() => _AutoCompleteFieldState();
}
class _AutoCompleteFieldState extends State<AutoCompleteField> {
@override
Widget build(BuildContext context) {
// access like this
print(widget.textEditingController);
return Container();
}
}
無狀態小部件的情況
class AutocompleteFiled extends StatelessWidget {
const AutocompleteFiled({Key? key, required this.textEditingController}) : super(key: key);
final TextEditingController textEditingController;
@override
Widget build(BuildContext context) {
print(textEditingController);
return Container();
}
}
在這樣的父類呼叫中
Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 12.0, top: 12.0),
child: Text(
"Marke",
style: TextStyle(
color: Colors.grey[800],
),
)),
AutocompleteField(textEditingController: labelTextController,)
],
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/498110.html
下一篇:Python類從類物件呼叫方法
