import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:provider/provider.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart'; class GiftChatPage extends StatefulWidget { @override _GiftChatPageState createState() => _GiftChatPageState(); } class _GiftChatPageState extends State { ScrollController _controller = ScrollController(); bool showGoBottom = true; bool _isDisposed = false; List _msgList = []; late RtmProvider provider; @override void initState() { super.initState(); _controller.addListener(_scrollListener); provider = Provider.of(context, listen: false); var msgList = provider.roomGiftMsgList; provider.msgGiftListener = _onNewMsg; _msgList.addAll(msgList ??= []); // 使用安全的方式初始化滚动位置 _initScrollPosition(); } void _scrollListener() { final position = _controller.position; // 容差范围(5像素)避免精度问题 const tolerance = 10.0; // 判断是否在第一个项目(颠倒列表的底部) final isAtBottom = position.pixels < position.minScrollExtent + tolerance; // 判断是否在最后一个项目(颠倒列表的顶部) // final isAtTop = position.pixels >= position.maxScrollExtent - tolerance; if (isAtBottom != showGoBottom) { showGoBottom = isAtBottom; if (!_isDisposed) { setState(() {}); } } } // 安全初始化滚动位置 void _initScrollPosition() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { if (_isDisposed) return; _controller.jumpTo(0.0); }); } _onNewMsg(Msg msg) { if (_isDisposed) return; // 如果组件已销毁,直接返回 if (msg.groupId == "-1000") { ///清屏 _msgList.clear(); setState(() {}); return; } if (!_msgList.contains(msg)) { setState(() { _msgList.insert(0, msg); }); _controller.jumpTo(0.0); } } @override void dispose() { _isDisposed = true; provider.msgGiftListener = null; _controller.removeListener(_scrollListener); _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, resizeToAvoidBottomInset: false, body: Stack( alignment: Alignment.bottomLeft, children: [ ListView.builder( reverse: true, controller: _controller, shrinkWrap: true, itemBuilder: (BuildContext context, int index) { return MsgItem( msg: _msgList[index], onClick: (SocialChatUserProfile? user) {}, ); }, itemCount: _msgList.length, ), Visibility( visible: !showGoBottom, child: GestureDetector( onTap: () { if (_controller.hasClients) { _controller.jumpTo(0.0); } }, child: Container( margin: EdgeInsets.symmetric(horizontal: width(15)), padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(52), color: Colors.white, ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( SCAppLocalizations.of(context)!.scrollToTheBottom, style: TextStyle(fontSize: 10.sp), ), SizedBox(width: 4.w), Icon(Icons.chevron_right, size: 10.w), ], ), ), ), ), ], ), ); } }