【问题标题】:Flutter: Autocomplete Textfield not working with custom data typeFlutter:自动完成文本字段不适用于自定义数据类型
【发布时间】:2019-09-25 04:47:59
【问题描述】:

我正在尝试构建一个具有自动完成功能的文本字段。我正在使用AutoComplete TextField 包。

我有带有 fromMaptoMap 方法的用户模型类。有从数据库中检索用户并返回用户列表List<Users>的功能。

这是构建自动完成字段的代码:

AutoCompleteTextField searchTextField = AutoCompleteTextField<Users>(
    key: key,
    clearOnSubmit: false,
    suggestions: users,
    style: TextStyle(color: Colors.black, fontSize: 16.0),
    decoration: InputDecoration(
      contentPadding: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
      hintText: "Search Name",
      hintStyle: TextStyle(color: Colors.black),
    ),
    itemFilter: (item, query) {
      return item.name.toLowerCase().startsWith(query.toLowerCase());
    },
    itemSorter: (a, b) {
      return a.name.compareTo(b.name);
    },
    itemSubmitted: (item) {
      setState(() {
        searchTextField.textField.controller.text = item.name;
      });
    },
    itemBuilder: (context, item) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Text(
            item.name,
          ),
        ],
      );
    },
  );

问。我是否遗漏了什么或做错了什么?

注意:

  1. users 对象包含格式正确的用户列表,我已打印以验证这一点。

【问题讨论】:

  • 你的问题是......? "Am I missing something or doing wrong?" 真的不多说了,是不是崩溃了?如果是这样,发布堆栈跟踪,如果不是,什么不起作用?
  • 它不会崩溃,也不会显示预期的结果。大约有 5 个用户的开头字母为A,当我输入A 时,它应该显示以A 开头的用户列表,但它没有显示任何内容。并且控制台中没有任何错误。但是,当我输入内容并在字段外点击时,它会显示此错误W/IInputConnectionWrapper( 5489): getCursorCapsMode on inactive InputConnection Exception caught by gesture The method 'where' was called on null. Receiver: null Tried calling: where(Closure: (Users) =&gt; bool)
  • 您正在使用pub.dev/packages/autocomplete_textfield?我遇到了很多问题,当我切换到 pub.dev/packages/flutter_typeahead 时这些问题就消失了(文档包更好)
  • 谢谢,我会用它。 1. 如何从项目中完全删除一个包? (想删除autocomplete_textfield包) 2.最后如何获得城镇名称?
  • 1.将其从pubspec.yaml 文件中删除,2. 数据取自 sqflite?

标签: flutter dart autocomplete autocompletetextview


【解决方案1】:

正如@pskink 提到的,

您正在使用autocomplete_textfield?我遇到了很多问题,当我切换到 flutter_typeahead 时这些问题就消失了(文档包更好)

所以我考虑了他的建议,并转移到flutter_typeahead 包。

final TextEditingController _typeAheadController = TextEditingController();

List<String> usersList;

//find and create list of matched strings
List<String> _getSuggestions(String query) {
    List<String> matches = List();

    matches.addAll(usersList);

    matches.retainWhere((s) => s.toLowerCase().contains(query.toLowerCase()));
    return matches;
}

//gets user list from db
void _getUsersList() async {
    usersList = await databaseHelper.getUsersList();
}


//the above code is defined in the class, before build method


//builds the text field
TypeAheadFormField(
  textFieldConfiguration: TextFieldConfiguration(
      controller: _typeAheadController,
      decoration: InputDecoration(labelText: 'Select a User'),
  suggestionsCallback: (pattern) {
    return _getSuggestions(pattern);
  },
  itemBuilder: (context, suggestion) {
    return ListTile(
      title: Text(suggestion),
    );
  },
  transitionBuilder: (context, suggestionsBox, controller) {
    return suggestionsBox;
  },
  onSuggestionSelected: (suggestion) {
    _typeAheadController.text = suggestion;

  },
  validator: (val) => val.isEmpty
      ? 'Please select a user...'
      : null,
  onSaved: (val) => setState(() => _name = val),
),



//function that pulls data from db and create a list, defined in db class
//not directly relevant but it may help someone
Future<List<String>> getUsersList() async {
    Database db = await instance.database;

    final usersData = await db.query("users");

    return usersData.map((Map<String, dynamic> row) {
      return row["name"] as String;
    }).toList();
}

PS:我想念autocomplete_textfield 的一件事是我们可以传递多个参数的方式,因为我们可以从我们自己的自定义模型(例如user 模型)继承。我知道这是可能的,但我是新手,所以仍然无法让它工作! :(

【讨论】:

  • 您不需要 getUsersList()method - 只需将 _getSuggestions(String pattern) 更改为返回 db.query("users", where: "name like %?%", whereArgs: [pattern]) - 仅此而已
  • 感谢您的建议,但它不起作用。我尝试了return await db.query('users', where: "name LIKE %?%", whereArgs: [pattern]),它抛出了Database Exception,所以我切换到return await db .rawQuery("SELECT * FROM users WHERE name LIKE '%$pattern%'");,但现在它抛出了Error: type 'Future&lt;dynamic&gt;' is not subtype of type 'FutureOr&lt;List&lt;dynamic&gt;&gt;'。我还尝试将_getSuggestions 定义为FutureOr&lt;List&lt;dynamic&gt;&gt;,但它会引发不同的错误:type 'QueryRow' is not a subtype of type 'String'
  • @pskink 我注意到typeahead 的一些奇怪之处。如果我像 _typeAheadController.text = "California"; 这样定义初始值,那么重新选择表单中的任何其他值都不起作用。当我们删除默认值并键入任何其他值时,它只会显示秒分割并变回默认值。你有什么想法,可能是什么问题? 注意: 如果我们删除初始值,那么它就可以正常工作。
  • 我不知道你说的"re-selecting any other value"是什么意思
  • 我会试试name LIKE ?,而re-selecting any other value的意思是当我们尝试选择任何值时;除了表单中的初始/默认值。
【解决方案2】:

我遇到了同样的问题,解决方案是放置一个布尔值并显示一个 CircularProgressIndicator 直到加载列表中的所有数据,从而呈现 AutoCompleteTextField

例如:


  _isLoading
                   ? CircularProgressIndicator ()
                   : searchTextField = AutoCompleteTextField <User> (your component here)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多