flutter 当键盘出现时自动滚动?

4ioopgfo  于 2023-06-07  发布在  Flutter
关注(0)|答案(1)|浏览(266)

我有一个聊天页面,其中有一个列表来显示消息。我想在键盘出现和发送新邮件时滚动到末尾。我该怎么解决?下面是我的代码:

Scaffold(
                            resizeToAvoidBottomInset: true,
                            appBar: AppBar(
                                leading: IconButton(
                                    onPressed: () {
                                      Navigator.pop(context);
                                    },
                                    icon: const Icon(Icons.arrow_back)),
                                elevation: 0,
                                centerTitle: true,
                                title: Text(
                                  widget.chatName!,
                                  overflow: TextOverflow.ellipsis,
                                )),
                            body:  Column(children: [
                                  Expanded(
                                    child: ListView.separated(
                                        shrinkWrap: true,
                                        controller: _controller,
                                        physics: const BouncingScrollPhysics(),
                                        itemBuilder: (context, index) {
                                           return Column(children: [
                                             SingleChatBubble(
                                                user: widget.user,
                                                message:
                                                    messageState.message[index])
                                          ]);
                                        },
                                        separatorBuilder: (context, index) =>
                                            const SizedBox(height: 5.0),
                                        itemCount: messageState.message.length),
                                  ),
                                  _messageSection(chatState.chat, otherUser)
                                ])));
cngwdvgl

cngwdvgl1#

我的方法是首先指定一个FocusNode并将其分配给消息发送方TextField。我会调整聊天室的initState方法:

@override
  void initState() {
    super.initState();
    // After the widget has been built 
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _focusNode.addListener(() async {
        if (_focusNode.hasFocus) {
          // If you remove the delay sometimes the scroll doesnt animate completely at the end
          await Future.delayed(const Duration(milliseconds: 150));
          _controller.animateTo(
            _controller.position.maxScrollExtent,
            duration: const Duration(milliseconds: 700),
            curve: Curves.easeOut,
          );
        }
      });
      // This is if you want to automatically toggle the keyboard when visitting the screen
      _focusNode.requestFocus();
    });
  }

这样,当您点击TextField时,无论您在哪里,消息都会在底部滚动。
我使用的整个示例代码:

class ChatRoom extends StatefulWidget {
  const ChatRoom({super.key});

  @override
  State<ChatRoom> createState() => _ChatRoomState();
}

class _ChatRoomState extends State<ChatRoom> {
  ScrollController _controller = ScrollController();
  FocusNode _focusNode = FocusNode();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _focusNode.addListener(() async {
        if (_focusNode.hasFocus) {
          // If you remove the delay sometimes the scroll doesnt animate completely at the end
          await Future.delayed(const Duration(milliseconds: 150));
          _controller.animateTo(
            _controller.position.maxScrollExtent,
            duration: const Duration(milliseconds: 700),
            curve: Curves.easeOut,
          );
        }
      });
      _focusNode.requestFocus();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
            onPressed: () {
              Navigator.pop(context);
            },
            icon: const Icon(Icons.arrow_back)),
        elevation: 0,
        centerTitle: true,
        title: Text(
          'chat name',
          overflow: TextOverflow.ellipsis,
        ),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView.separated(
              controller: _controller,
              physics: const BouncingScrollPhysics(),
              itemBuilder: (context, index) {
                return Column(children: [
                  SizedBox(
                    width: 200,
                    height: 100,
                    child: Text('text $index'),
                  ),
                ]);
              },
              separatorBuilder: (context, index) => const SizedBox(height: 5.0),
              itemCount: 35,
            ),
          ),
          TextField(
            focusNode: _focusNode,
            decoration: InputDecoration(
              hintText: 'Type a message',
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(50),
              ),
              suffixIcon: IconButton(
                onPressed: () {},
                icon: const Icon(Icons.send),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

相关问题