使用typeahead包时,我没有得到所需的结果。
当前不良行为:
-
当我点击文本字段时,在我开始键入之前,我会立即看到所有建议的列表(超过26000(
-
当我开始打字时,建议列表不会调整(例如,如果我键入"a",则显示完整的建议列表,并且该列表不会过滤为仅显示以"a"开头的建议
预期结果:
- 我只是想让这个功能根据我键入的内容向我展示建议——我肯定我的代码实现错了,我真的很感激任何帮助
我的相关代码:
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import '../providers/analysis_route_provider.dart';
class AutoCompleteTextfieldTwo extends StatefulWidget {
@override
_AutoCompleteTextfieldTwoState createState() =>
_AutoCompleteTextfieldTwoState();
}
class _AutoCompleteTextfieldTwoState extends State<AutoCompleteTextfieldTwo> {
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return TypeAheadField(
hideOnEmpty: true,
textFieldConfiguration: TextFieldConfiguration(
style: TextStyle(
color: Colors.white,
),
autofocus: false,
controller: this._controller,
keyboardType: TextInputType.text,
enabled: true,
focusNode: FocusNode(),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(
width: 2,
color: Colors.blue,
),
),
hintText: 'Type in company name or ticker symbol',
hintStyle: TextStyle(
color: Colors.grey,
),
),
),
getImmediateSuggestions: true,
hideOnError: true,
suggestionsCallback: (pattern) async {
return await AnalysisRouteProvider.getCompaniesForTextfield2(pattern);
},
itemBuilder: (context, itemData) {
return ListTile(
title: Text(itemData['name'].toString()),
subtitle: Text(itemData['symbol'].toString()),
);
},
onSuggestionSelected: (suggestion) {
print('selected');
FocusNode().unfocus();
this._controller.text = suggestion['name'].toString();
_controller.clear();
},
);
}
}
Http请求:
static Future getCompaniesForTextfield2(String query) async {
var url = *url with api key here*;
http.Response response = await http.get(url, headers: {
'Content-Type': 'application/json',
});
var jsonData = json.decode(response.body);
return jsonData;
}
JSON片段(API实际返回的对象超过26000个(:
[ {
"symbol" : "SPY",
"name" : "SPDR S&P 500",
"price" : 326.7,
"exchange" : "NYSE Arca"
}, {
"symbol" : "CMCSA",
"name" : "Comcast Corp",
"price" : 41.98,
"exchange" : "Nasdaq Global Select"
}, {
"symbol" : "KMI",
"name" : "Kinder Morgan Inc",
"price" : 11.83,
"exchange" : "New York Stock Exchange"
}]
我也确信这一点信息是相关的。目前,当我调试并点击typeahead文本字段时,我会在调试控制台中得到以下内容:
W/IInputConnectionWrapper(13704): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(13704): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(13704): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(13704): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(13704): endBatchEdit on inactive InputConnection
我认为应该在false
上设置getImadiateSugetions
,以禁用在Tap上显示建议列表。
关于第二个问题,您没有得到suggetions,我认为问题在json中,您使用的是json.decode,它解码[]
中要列出的任何json,如果它在{}
中,则在map中解码,所以我认为您应该执行以下操作:
suggestionsCallback: (pattern) async {
var list = await AnalysisRouteProvider.getCompaniesForTextfield2(pattern);
return list[0];
},
- 要解决第一个问题,只需添加
minCharsForSuggestions
属性
示例:
TypeAheadField(
minCharsForSuggestions: 3,
)
- 要解决第二个问题,您应该在建议列表中添加一些筛选器
示例:
suggestionsCallback: (pattern) {
return await AnalysisRouteProvider.getCompaniesForTextfield2(pattern).where(
(e) => e['name'].toLowerCase().startsWith(
pattern.toLowerCase(),
),
);
},