在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘

Posted

技术标签:

【中文标题】在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘【英文标题】:Hide/Dismiss keyboard on ListView scroll in Flutter app 【发布时间】:2019-09-29 17:33:57 【问题描述】:

我在 Flutter 应用中有聊天窗口。 消息在ListView 小部件中显示为小部件,我还在窗口底部附加了用于消息输入的小部件。

我想要

    滚动ListView时隐藏键盘 从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】:

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

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

【讨论】:

漂亮,当你有一个单行时谁需要一个滚动控制器【参考方案2】:

关于你们的第 1 点问题:

您可以为listScrollController 创建一个监听器函数,其中包含对匿名FocusNode 的调用(想法来自这个高度投票的answer),当任何滚动事件发生时,焦点将从您的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);
    )
  ]
 )

【讨论】:

谢谢,看来它可以按预期工作了!我现在意识到,当显示键盘时,一些消息会被键盘溢出,所以我需要相应地滚动我的 ListView? 一点也不!顺便说一句,我在发布之前测试了代码。 你能在评论中推荐一些有问题的东西吗? 哪种溢出?你能解释一下吗? 一些在没有键盘的情况下看到的消息现在隐藏在显示的键盘后面。所以当键盘出现时我需要向上移动消息【参考方案3】:

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

    将类更改为StatefullWidget 创建final ScrollController listScrollController = ScrollController();

    ListView 应该是这样的:

         ListView.builder(
              controller: listScrollController,
              reverse: true,
    

    如果你像这样使用 firebase 变更单:

    .orderBy('timestamp', descending: true)

    将此代码添加到您的发送按钮中

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

自动向上滚动您的文本字段,在Stack 中添加您的textFieldListView

【讨论】:

以上是关于在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中的 ListView 中搜索(使用 Firebase 中的数据)

在 Flutter 中的垂直 ScrollView 内的水平 ListView 中显示来自 Firestore 的数据

Flutter中的ListView动态排序

Flutter - 另一个 Listview 中的 Listview.builder

ListView Flutter 中的 ListViews

检查 ListView 中的一个 CheckBox 使用 Flutter 来检查所有其余的 CheckBox