Flutter 聊天页面,ListView reverse 后,怎么能让消息保持在顶部

fanta_zz
  • 1
新手上路,请多包涵

在一个普通的聊天页面里。用ListView布局,然后reverse反转。

可以看到现在旧的消息都底部,当有新的消息的时候,会插入到底部。

我希望当聊天内容很少,不足以填充整个页面的时候,旧消息是保持在顶部的。

怎么能实现呢?

1. 不反转就能让消息在顶部,为什么一定反转

系统可能在任何时候,跳转list的最底部。反转可以很容易的通过scrollController.jumpTo(0)跳转到底部。

如果不反转可能因为键盘遮挡等原因,通过scrollController.position.maxScrollExtent无法跳转到底部。

2. Alignalignment: centerTop 可以解决吗

可以很容易搜索到一个方案,用alignmentListView置顶。但是这有一个问题,因为ListView的内容很少,这时候滚动的时候,无法正常显示。

回复
阅读 794
1 个回答
áǎáUgu5w
  • 4
新手上路,请多包涵

这样试下?:

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

class TestChatPage extends StatefulWidget {
  const TestChatPage({Key? key}) : super(key: key);

  @override
  State<TestChatPage> createState() => _TestChatPageState();
}

class _TestChatPageState extends State<TestChatPage> {
  List<String> msgs = ['hello 0'];
  ScrollController scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    initItems();
  }

  void initItems() {
    Timer.periodic(const Duration(milliseconds: 200), (timer) {
      msgs.add('hello ${msgs.length}');
      setState(() {});
    });
  }

  void _onSendClicked() {
    scrollController.animateTo(
      0,
      duration: const Duration(milliseconds: 200),
      curve: Curves.ease,
    );
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Column(
          children: [
            Expanded(
              child: SingleChildScrollView(
                reverse: true,
                controller: scrollController,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children:
                      List.generate(msgs.length, (index) => Text(msgs[index])),
                ),
              ),
            ),
            Container(
              height: 56,
              padding: EdgeInsets.all(6),
              child: Row(
                children: [
                  const Expanded(child: TextField()),
                  TextButton(onPressed: _onSendClicked, child: Text("Send"))
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏