Flutter - 在其他小部件上方显示建议列表

3

我正在开发一个屏幕,在这个屏幕上,我需要在textfield下方显示建议列表。

我想实现如下效果:

enter image description here

目前,我已经开发出以下内容:

enter image description here

下面的代码展示了一个包含建议列表的textfield

  @override
  Widget build(BuildContext context) {
    final header = new Container(
      height: 39.0,
      padding: const EdgeInsets.only(left: 16.0, right: 2.0),
      decoration: _textFieldBorderDecoration,
      child: new Row(
        children: <Widget>[
          new Expanded(
            child: new TextField(
              maxLines: 1,
              controller: _controller,
              style: _textFieldTextStyle,
              decoration:
                  const InputDecoration.collapsed(hintText: 'Enter location'),
              onChanged: (v) {
                _onTextChanged.add(v);
                if (widget.onStartTyping != null) {
                  widget.onStartTyping();
                }
              },
            ),
          ),
          new Container(
            height: 32.0,
            width: 32.0,
            child: new InkWell(
              child: new Icon(
                Icons.clear,
                size: 20.0,
                color: const Color(0xFF7C7C7C),
              ),
              borderRadius: new BorderRadius.circular(35.0),
              onTap: (){
                setState(() {
                  _controller.clear();
                  _places = [];
                  if (widget.onClearPressed != null) {
                    widget.onClearPressed();
                  }
                });
              },
            ),
          ),
        ],
      ),
    );

    if (_places.length > 0) {
      final body = new Material(
        elevation: 8.0,
        child: new SingleChildScrollView(
          child: new ListBody(
            children: _places.map((p) {
              return new InkWell(
                child: new Container(
                  height: 38.0,
                  padding: const EdgeInsets.only(left: 16.0, right: 16.0),
                  alignment: Alignment.centerLeft,
                  decoration: _suggestionBorderDecoration,
                  child: new Text(
                    p.formattedAddress,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 1,
                    style: _suggestionTextStyle,
                  ),
                ),
                onTap: () {
                  _getPlaceDetail(p);
                },
              );
            }).toList(growable: false),
          ),
        ),
      );

      return new Container(
        child: new Column(
          children: <Widget>[header, body],
        ),
      );
    } else {
      return new Container(
        child: new Column(
          children: <Widget>[header],
        ),
      );
    }
  }

头部(Textfield)和主体(建议列表 - SingleChildScrollViewListBody)被包装在Column小部件中,列根据子项的总高度扩展。现在的问题是,随着列的扩展,布局系统将屏幕上的其他小部件推到底部。但我希望其他小部件保持在它们的位置上,但建议列表开始出现在其他小部件的顶部。

如何在其他小部件的顶部显示建议列表?并且建议列表是动态的,当用户输入时,我调用Google Places API并更新建议列表。

我看到有一个showMenu<T>()方法与RelativeRect位置,但它不能实现我的目的,我的建议列表是动态的(根据用户输入变化),每个项目的样式与PopupMenuItem提供的不同。

我能想到的一种可能性是使用Stack小部件作为此屏幕的根小部件,并通过绝对位置排列所有内容,然后将建议列表放置在堆栈子列表的最后一个子项中。但我认为这不是正确的解决方案。

我需要查看哪些其他可能性?在这种情况下可以使用哪些其他小部件?

再次强调,用例很简单,在屏幕上覆盖建议列表,当用户从列表中点击任何项目时,隐藏此覆盖的建议列表。


这不是完整的答案,因为它并没有真正解决你所问的直接问题。但是你见过这个包吗?(https://pub.dartlang.org/packages/flutter_google_places_autocomplete#-readme-tab-) 它可能以更少的麻烦实现你要找的功能,或者至少你可以利用其中的部分。它不是在线完成自动完成,而是推送到另一个页面……这样做的好处是最大化屏幕上的建议空间。 - rmtmckenzie
谢谢@rmtmckenzie,我已经看过了,这正是我正在做的事情,但是我采用了不同的方式。我也查看了该包中的代码,以了解是否有相关的覆盖小部件的代码,但我没有找到任何相关的内容。但还是感谢您的回答。 - Muhammad Ahmed
1
你应该查看https://medium.com/saugo360/https-medium-com-saugo360-flutter-using-overlay-to-display-floating-widgets-2e6d0e8decb9以及https://pub.dartlang.org/packages/flutter_typeahead的示例,了解如何实现这个功能。 - Simon
1个回答

2
您的自动完成列表将下面的小部件向下推的原因是因为列表正在容器上进行扩展。您可以使用Flutter的自动完成小部件,它应该会将自动完成列表放置在其他小部件之上。
var fruits = ['Apple', 'Banana', 'Mango', 'Orange'];

_autoCompleteTextField() {
  return Autocomplete(
    optionsBuilder: (TextEditingValue textEditingValue) {
      if (textEditingValue.text == '') {
        return const Iterable<String>.empty();
      }
      return fruits.where((String option) {
        return option
            .toLowerCase()
            .contains(textEditingValue.text.toLowerCase());
      });
    },
    onSelected: (String selection) {
      debugPrint('You just selected $selection');
    },
  );
}

Demo


你解决了列表没有展开到屏幕末端的问题吗? - San Juan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接