flutter - 聊天的输入框键盘向上推送消息列表

use*_*710 1 flutter

我有一个相当简单的颤振应用程序。它有聊天功能。但是,我的聊天功能有问题。它由一个小部件 Scaffold 和其中的 SingleChildScrollView 组成 - 它有一个消息列表(容器)和输入区域(容器)。代码附后。

问题是:如果我单击输入框,键盘将打开并推送消息列表。如果您已经位于消息列表的底部,则推送消息列表是可以接受的事情。但是,如果用户向上滚动并看到一些旧消息,我不希望向上推送消息列表小部件。另外,如果我只有少量消息,我不希望消息列表被推送(因为这只会让消息在键盘打开时消失,然后我需要滚动到已推送的消息) [用户在滚动之前会留下 0 条可见消息])。

我尝试了不同的方法 - 比如

  resizeToAvoidBottomInset: false
Run Code Online (Sandbox Code Playgroud)

但似乎没有什么对我有用,这似乎应该是一个简单的行为(例如,whatsapp 的行为就像所需的行为)。我担心的唯一选择是监听键盘打开事件,但我希望有一个更优雅的解决方案。

这是我的代码:

  @override
  Widget build(BuildContext context) {
    height = MediaQuery.of(context).size.height;
    width = MediaQuery.of(context).size.width;
    return Scaffold(
        body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            SizedBox(height: height * 0.1),
            buildMessageList(), // container
            buildInputArea(context), // container
          ],
        ),
      ),
    );


  Widget buildInputArea(BuildContext context) {
    return Container(
      height: height * 0.1,
      width: width,
      child: Row(
        children: <Widget>[
          buildChatInput(),
          buildSendButton(context),
        ],
      ),
    );
  }

  Widget buildMessageList() {
    return Container(
      height: height * 0.8,
      width: width,
      child: ListView.builder(
        controller: scrollController,
        itemCount: messages.length,
        itemBuilder: (BuildContext context, int index) {
          return buildSingleMessage(index);
        },
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

Han*_*ård 5

这似乎对我有用:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ScrollController _controller = ScrollController();

  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            buildMessageList(),
            buildInputArea(context),
          ],
        ),
      ),
    );
  }

  Widget buildInputArea(BuildContext context) {
    return Row(
      children: <Widget>[
        Expanded(
          child: TextField(),
        ),
        RaisedButton(
          onPressed: null,
          child: Icon(Icons.send),
        ),
      ],
    );
  }

  Widget buildMessageList() {
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        itemCount: 50,
        controller: _controller,
        itemBuilder: (BuildContext context, int index) {
          return Padding(
            padding: EdgeInsets.all(10),
            child: Container(
              color: Colors.red,
              height: 20,
              child: Text(index.toString()),
            ),
          );
        },
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我认为问题在于您对所有小部件使用固定大小。在这种情况下,最好使用ExpandedListView删除SingleChildScrollView。这样整个内容Column就不会滚动,而只有ListView.