Hide/Dismiss Flutter 应用中 ListView 滚动时的键盘

Hide/Dismiss keyboard on ListView scroll in Flutter app

我在 Flutter 应用中聊天 window。 消息在 ListView 小部件内显示为小部件,我还在 window.

底部附加了用于消息输入的小部件

我想

  1. 滚动 ListView
  2. 时隐藏键盘
  3. InputWidget 添加新消息时滚动到最后一条消息

代码:

class _MessagesPageState extends State<MessagesPage> {
  final ScrollController listScrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
    ....
    body: Stack(
        children: [
          ListView.builder(
              controller: listScrollController
              ....
          ),
          InputWidget()]
    );
}

class InputWidget extends StatelessWidget {

  final TextEditingController _textEditingController = TextEditingController();

....
Row (
  children: [
    TextField(
     controller: _textEditingController
    ), 
    IconButton(icon: ...., onPressed: (){})
  ]
 )}

关于第 1 点问题:

您可以为 listScrollController 创建一个侦听器函数,其中包含对匿名 FocusNode 的调用(这个想法取自这个高票数 ),并且当任何滚动事件发生时,聚焦将从您的 TextField 中获取并且键盘将被关闭:

 class _MessagesPageState extends State<MessagesPage> {

 final ScrollController listScrollController = ScrollController();

 @override
 void initState() {
   listScrollController.addListener(_scrollListener);
   super.initState();
 }

 _scrollListener() {
   FocusScope.of(context).requestFocus(FocusNode());
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
   ....
   body: Stack(
    children: [
      ListView.builder(
          controller: listScrollController
          ....
      ),
      InputWidget(controller: listScrollController)]
   );
}

第 2 点:

您会注意到我修改了您的 InputWidget 以将 ScrollController 作为参数,因此您可以将 ListView 控制器传递给它。当按下 IconButton 时,listScrollController 将根据您的需要跳到结尾。

 class InputWidget extends StatelessWidget {

 InputWidget({Key key,this.controller}) : super(key: key);

 final ScrollController controller ;

 final TextEditingController _textEditingController = TextEditingController();

 ....
 Row (
  children: [
    TextField(
      controller: _textEditingController
    ), 
    IconButton(icon: ...., onPressed: (){
      controller.jumpTo(controller.position.maxScrollExtent);
    })
  ]
 )}

很简单..按照这些步骤..

  1. 将class更改为StatefullWidget
  2. 创建final ScrollController listScrollController = ScrollController();
  3. ListView应该是这样的:

         ListView.builder(
              controller: listScrollController,
              reverse: true,
    
  4. 如果你像这样使用 firebase 更改顺序:

    .orderBy('timestamp', descending: true)

  5. 在您的“发送”按钮中添加此代码

listScrollController.animateTo(0.0,duration: Duration(milliseconds: 300), curve: Curves.easeOut);

自动向上滚动您的文本字段,在 Stack

中添加您的 textFieldListView

要在列表视图滚动时隐藏键盘,只需添加 keyboardDismissBehavior 即可。示例

ListView(
 keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
 children: [],
)