【问题标题】:Why AutoCompleteTextField is not showing any suggestion in Flutter?为什么 AutoCompleteTextField 在 Flutter 中没有显示任何建议?
【发布时间】:2021-01-09 13:44:41
【问题描述】:

我是 Flutter 的新手,目前正在从事一个项目,我需要向用户显示匹配成员的列表,以便用户可以轻松地选择其中一个。为此,我使用 AutoCompleteTextField。只要已获取的成员列表提供给它的建议属性,它就可以正常工作。但我想知道,为什么当我把它放在 BlocBuilder 下时它不起作用。事件命中 textChanged 方法,状态也返回一个列表,但建议是不可见的。

  Widget autoCompleteSearchBar() {
    return BlocBuilder<OrderInfoBloc, MyOrderInfoStates>(
      builder: (context, state) {
          return AutoCompleteTextField<Member>(
            clearOnSubmit: false,
            style: TextStyle(
              color: Colors.black,
              fontSize: 16,
            ),
            decoration: InputDecoration(
              hintText: 'Search Member Here..',
              border: InputBorder.none,
              suffixIcon: IconButton(
                icon: Icon(Icons.cancel),
                iconSize: 20,
                color: Colors.yellow[700],
                onPressed: () {
                  _autoCompleteController.text = "";
                },
              ),
              contentPadding: EdgeInsets.fromLTRB(10, 30, 10, 20),
              hintStyle: TextStyle(color: Colors.grey),
            ),
            keyboardType: TextInputType.text,
            controller: _autoCompleteController,
            textChanged: (value) {
              context.read<OrderInfoBloc>().add(SearchTextChanged(text: value));
            },
            itemSubmitted: (item) async {
              _autoCompleteController.text = state.radioGroupValue == 'By Code'
                  ? item.memberNo
                  : item.memberName;
              context.read<OrderInfoBloc>().add(SelectedMember(member: item));
            },
            key: _key,
            suggestions: state.membersList,
            itemBuilder: (context, item) {
              print(item);
              // return state.radioGroupValue == 'By Code'
              //     ? autoCompleteSearchBarRow(
              //         item: item.memberNo, icon: Icon(Icons.person))
              //     : autoCompleteSearchBarRow(
              //         item: item.memberName, icon: Icon(Icons.person));
              return autoCompleteSearchBarRow(
                  item: item.memberNo, icon: Icon(Icons.person));
            },
            itemFilter: (item, query) {
              print(query);
              // bool _itemFilter;
              // if (_autoCompleteController.text.isNotEmpty) {
              //   _itemFilter = state.radioGroupValue == 'By Code'
              //       ? item.memberNo
              //           .toLowerCase()
              //           .startsWith(query.toLowerCase())
              //       : item.memberName
              //           .toLowerCase()
              //           .startsWith(query.toLowerCase());
              // } else {
              //   _autoCompleteController.text = '';
              //   _itemFilter = false;
              // }
              // return _itemFilter;
              return item.memberNo.toLowerCase().startsWith(query.toLowerCase());
            },
            itemSorter: (a, b) {
              // return state.radioGroupValue == 'By Code'
              //     ? a.memberNo.compareTo(b.memberNo.toLowerCase())
              //     : a.memberName.compareTo(b.memberName.toLowerCase());
              print(b);
              return a.memberNo.compareTo(b.memberNo.toLowerCase());
            },
          );
        }
    );
  }

  Widget autoCompleteSearchBarRow(
      {@required String item, @required Icon icon}) {
    return ListTile(
      leading: icon,
      title: Text(item),
    );
  }

【问题讨论】:

    标签: flutter flutter-bloc simpleautocompletetextfield


    【解决方案1】:

    使用flutter_typeahead 包,它与flutter bloc 配合得很好

    现在,来到 bloc 方面,您不需要使用 blocbuilder 包装自动完成小部件,因为如果这样做,每当事件触发时,bloc 总是会重新绘制小部件。因此,在您的情况下,当您在文本框中输入时,事件会触发并 bloc 重建小部件,并且由于该建议不会出现,即使您看到建议,一旦相应的 bloc 状态发生并重建小部件,它们也会消失

    推荐的解决方案如下所示

    不要添加任何状态来获取建议,只需从事件返回结果或记录,如下所示。 (以下函数添加到 Cubit 文件中)

      Future<List<Item>> getProductItemsBySearchString(String item) async {
        return await itemRepository.getItemsByName(item);
      }
    

    正如您在上面看到的,我直接从 getProductItemsBySearchString() 事件方法返回项目记录(无 bloc 状态)

    然后像下面这样使用它

    class ItemScreen extends StatelessWidget {
      // then you can call bloc event in function as below
      Future<List<Item>> getItemSuggestionsList(
          BuildContext context, String text) async {
        final bloc = context.read<ItemCubit>();
    
        List<Item> data = await bloc.getProductItemsBySearchString(text);
    
        if (data != null) {
          return data;
        } else {
          return null;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return TypeAheadField(
          getImmediateSuggestions: true,
          textFieldConfiguration: TextFieldConfiguration(
              controller: _itemEditingController,
              autofocus: false),
          suggestionsCallback: (pattern) {
            // call the function to get suggestions based on text entered
            return getItemSuggestionsList(context, pattern);
          },
          itemBuilder: (context, suggestion) {
            // show suggection list
            return Padding(
              padding: const EdgeInsets.all(8.0),
              child: ListTile(
                title: Text(suggestion.name),
                trailing: Text(
                  'Item Code: ${suggestion.code}',
                ),
              ),
            );
          },
          onSuggestionSelected: (suggestion) {
           // get selected suggesion
          },
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      相关资源
      最近更新 更多