我正在创建一个原始的自动完成小部件。问题是,如果小部件位于屏幕的中心或底部周围,当我开始输入时,显示的自动建议会隐藏在软键盘下。如何构建optionsViewBuilder来克服键盘下选项的隐藏?
示例源代码:
class AutoCompleteWidget extends StatefulWidget {
const AutoCompleteWidget(
Key key,
) : super(key: key);
@override
_AutoCompleteWidgetState createState() => _AutoCompleteWidgetState();
}
class _AutoCompleteWidgetState extends State<AutoCompleteWidget> {
late TextEditingController _textEditingController;
String? _errorText;
final FocusNode _focusNode = FocusNode();
final GlobalKey _autocompleteKey = GlobalKey();
List<String> _autoSuggestions = ['abc', 'def', 'hij', 'aub', 'bted' 'donfr', 'xyz'];
@override
void initState() {
super.initState();
_textEditingController = TextEditingController();
}
@override
void dispose() {
_textEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return RawAutocomplete<String>(
key: _autocompleteKey,
focusNode: _focusNode,
textEditingController: _textEditingController,
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return _autoSuggestions;
}
return _autoSuggestions.where((dynamic option) {
return option
.toString()
.toLowerCase()
.startsWith(textEditingValue.text.toLowerCase());
});
},
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
return Material(
elevation: 4.0,
child: ListView(
children: options
.map((String option) => GestureDetector(
onTap: () {
onSelected(option);
},
child: ListTile(
title: Text(option),
),
))
.toList(),
),
);
},
fieldViewBuilder: (
BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onSubmitted,
) {
return Card(
elevation: (null == _errorText ? 8 : 0),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: TextField(
controller: textEditingController,
focusNode: focusNode,
),
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
我想出的一个解决方案是使用TextFormField和 设置来构建我自己版本的简单自动完成小部件scrollPadding。我在一个容器中显示结果,该容器具有与该填充一起使用的设定高度。
@override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: [
// THE AUTOCOMPLETE INPUT FIELD
TextFormField(
focusNode: _focusNode,
scrollPadding: const EdgeInsets.only(bottom: 300),
maxLines: null,
key: const ValueKey('company_address'),
autocorrect: false,
enableSuggestions: false,
controller: widget.textEditingController,
validator: (value) {
if (value!.isEmpty) {
return _i10n.enterAName;
}
return null;
},
decoration: InputDecoration(
labelText: widget.labelText,
),
textInputAction: TextInputAction.next,
onChanged: (_) {
_handleChange();
widget.onChange();
},
onTap: () {
setState(() {
_showAutocompleteSuggestions = true;
});
},
),
const SizedBox(
height: 5.0,
),
// THE AUTOCOMPLETE RESULTS
if (_showAutocompleteSuggestions)
Container(
// height: _autocompleteHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: const [
BoxShadow(blurRadius: 10.0, color: Colors.black12)
],
color: Colors.white,
),
constraints: const BoxConstraints(maxHeight: 200.0),
child: Scrollbar(
child: SingleChildScrollView(
child: Column(children: [
if (_autocompleteSuggestions.isEmpty)
const ListTile(
title: Text('No results'),
)
else
..._autocompleteSuggestions.map((_autocompleteSuggestion) =>
Material(
child: InkWell(
onTap: () {
_handleSelectSuggestion(_autocompleteSuggestion);
},
child: ListTile(
leading: const Icon(Icons.location_on_outlined),
title: Text(_autocompleteSuggestion.description),
),
),
))
]),
),
),
),
],
);
}
Run Code Online (Sandbox Code Playgroud)
请原谅快速转储代码。
| 归档时间: |
|
| 查看次数: |
3121 次 |
| 最近记录: |