【问题标题】:How to use a stack correctly?如何正确使用堆栈?
【发布时间】:2021-07-19 16:33:04
【问题描述】:

IM 试图使用一个堆栈,我在其中显示一个列表视图和一个 这是我的代码

@override
  Widget build(BuildContext context) {
    final user = Provider.of<Userforid>(context);
    _deviceHeigth = MediaQuery.of(context).size.height;
    _deviceWidth = MediaQuery.of(context).size.width;
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0.0,
        title: Text(this.widget._receivername),
      ),
      body: StreamBuilder<UserData>(
        stream: DatbaseService(uid: user.uid).userData,
        builder: (context, snapshot) {
          return _conversationPageUI();
        },
      ),
    );

然后是 _conversationPageUI();这是这里吗

 Widget _conversationPageUI() {
    return Builder(builder: (BuildContext _context) {
      return Stack(
        overflow: Overflow.visible,
        children: <Widget>[
          _messageLisView(),
          Align(
            alignment: Alignment.bottomCenter,
            child: _messageField(_context),
          ),
        ],
      );
    });
  }

然后每个小部件都在这里

Widget _messageLisView() {
    final user = Provider.of<Userforid>(context);
    return Container(
      width: _deviceWidth,
      child: StreamBuilder<Conversation>(
        stream: DatbaseService.instance
            .getConversation(this.widget._convertsationID),
        builder: (BuildContext _context, _snapshot) {
          if (_listViewController.hasClients) {
            _listViewController.animateTo(
                _listViewController.position.maxScrollExtent,
                duration: const Duration(milliseconds: 200),
                curve: Curves.easeOut);
          }
          var _conversationData = _snapshot.data;
          if (_conversationData != null) {
            if (_conversationData.messages != null) {
              return ListView.builder(
                controller: _listViewController,
                padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                itemCount: _conversationData.messages.length,
                itemBuilder: (BuildContext _context, int _index) {
                  var _message = _conversationData.messages[_index];
                  bool _isOwnMessage = _message.senderID == user.uid;
                  return _messageListViewChild(_isOwnMessage, _message);
                },
              );
            } else {
              return Align(
                alignment: Alignment.center,
                child: Text("Let's start a Conversation"),
              );
            }
          } else {
            return Center(
                child: Container(
              child: CircularProgressIndicator(),
            ));
          }
        },
      ),
    );
  }

  Widget _messageField(BuildContext _context) {
    return Container(
      height: _deviceHeigth * 0.07,
      decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(100),
          border: Border.all(color: Colors.black, width: 2)),
      margin: EdgeInsets.symmetric(
          horizontal: _deviceWidth * 0.04, vertical: _deviceHeigth * 0.03),
      child: Form(
        key: _formKey,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            _messageTextField(),
            _sendMessageButton(_context),
            _videoMessageButton(),
          ],
        ),
      ),
    );
  }

_messageField 只是一个带有提示文本和 2 个图标的 Textformfield。这是它的外观

如您所见,我无法正确看到最后一个列表视图项目,这就是我的问题,我该如何解决?

【问题讨论】:

  • 我不认为 Stack 是这里小部件的正确选择。您可以使用BottomSheet 作为文本框。然后将Padding 添加到body of Scaffold。它应该适合你。

标签: firebase flutter google-cloud-firestore material-design


【解决方案1】:
Padding(
    padding: const EdgeInsets.only(bottom:MediaQuery.of(context).size.height * 0.1),
child: ListView.builder(
            controller: _listViewController,
            padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
            itemCount: _conversationData.messages.length,
            itemBuilder: (BuildContext _context, int _index) {
              var _message = _conversationData.messages[_index];
              bool _isOwnMessage = _message.senderID == user.uid;
              return _messageListViewChild(_isOwnMessage, _message);
            },
          ),
         )

//或

sizedBox(
    height: MediaQuery.of(context).size.height * 0.80,
child: ListView.builder(
            controller: _listViewController,
            padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
            itemCount: _conversationData.messages.length,
            itemBuilder: (BuildContext _context, int _index) {
              var _message = _conversationData.messages[_index];
              bool _isOwnMessage = _message.senderID == user.uid;
              return _messageListViewChild(_isOwnMessage, _message);
            },
          ),
         )

【讨论】:

  • 好的,我刚刚使用了填充:EdgeInsets.only(bottom:90),但是当我来到这个页面时,maxscrollextent 滚动不正确,为什么?
  • 这仅仅是因为您的 textField 在底部对齐,将您的 messagefield 放在 Scaffold(bottomsheet: ) 中,您仍然需要对其 ThemeData 进行一些小的更改。请上传 maxscrollextent 对您的 UI 所做的操作的屏幕截图。
  • 或者您可以使用高度为 SizedBox 的列表视图:MediaQuery.of(context).size.height * 0.80
【解决方案2】:

我认为通过

fit: StackFit.expand,

到您的堆栈小部件将解决您的问题。

【讨论】:

    【解决方案3】:

    只需在列表视图底部添加填充:

    Widget _messageLisView() {
        final user = Provider.of<Userforid>(context);
        return Container(
          padding: EdgeInsets.only(bottom: 100),
          width: _deviceWidth,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 2018-03-10
      • 2010-09-28
      • 2019-04-29
      • 2018-10-02
      相关资源
      最近更新 更多