在我的聊天应用程序中,当后端有更新/新数据时,我试图自动更新列表。我使用StreamBuilder来做到这一点,但当后端数据更改时,它不会更新ListView。我在后台服务器端使用的是一个带有mysql作为数据库的spring Boot 服务器。我发现的大多数聊天应用程序示例都是基于firebase作为服务器的,这并没有帮助我解决这个问题。我在这里做错了什么,请帮助纠正这个问题,因为我是一个flutter初学者。
class ChatScreen extends ConsumerStatefulWidget {
final dynamic data;
final dynamic category;
const ChatScreen({
Key? key, required this.data, required this.category,
}) : super(key: key);
@override
ConsumerState<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends ConsumerState<ChatScreen> with SingleTickerProviderStateMixin {
dynamic dataItem;
List<dynamic>? chatList = [];
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: WillPopScope(
child: showChat(),
),);
}
showChat() {
return StreamBuilder<dynamic>(
stream: ref.watch(chatControllerProvider).getChatsList(widget.data['id'],widget.category['id']),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Loader();
} else if(snapshot.data!.isEmpty) {
return NoChat();
} else {
dataItem = snapshot.data!['chatRoom'];
chatList = snapshot.data!['chatList'];
return showChatView();
}
},);
}
showChatView() {
int dataLength = chatList!.length;
return Column(
children: [
Expanded(child: ListView(
reverse: true,
padding: EdgeInsets.all(20),
children: List.generate(chatList!.length, (index) {
return MessageBox(
data: chatList![dataLength - 1 - index],
);
},),
),),
],
);
}
}
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../chat_repository.dart';
final chatControllerProvider = Provider<ChatController>(
(ref) {
final chatApi = ref.watch(chatRepositoryProvider);
return ChatController(chatApi: chatApi, ref: ref);
},
);
class ChatController {
ChatController({
required ChatApi chatApi,
required ProviderRef ref,
}) : _chatApi = chatApi,
_ref = ref;
final ChatApi _chatApi;
final ProviderRef _ref;
Stream<dynamic> getChatsList(int roomId,int categoryId) async* {
var result = await _chatApi.getRoomChatList(roomId,categoryId);
yield result;
}
}
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '...../chat_api.dart';
final chatRepositoryProvider = Provider<ChatApi>((ref) {
return ChatApi();
});
class ChatApi{
late Dio dioRest;
ChatApi() {
dioRest = Dio(
BaseOptions(
headers: {
HttpHeaders.contentTypeHeader: ContentType.json.value,
},
),
);
}
Future getRoomChatList(int roomId,int categoryId) async {
try {
token = getToken();
var result = await dioRest.post(token.baseUrl!+'..../getRoomChatList',options: Options(.....),
queryParameters: {'roomId' : roomId,'categoryId' : categoryId},
);
if (result.statusCode == 200) {
return jsonDecode(result.data);
}
throw DioError(requestOptions: result.requestOptions);
} on DioError catch (error) {
if (error.response!.statusCode! >= 400) {
throw TokenException(message: "Token invalid or expired");
}
throw BusinessException(BusinessError.fromJson(error.response?.data), statusCode: error.response?.statusCode);
} catch (error) {
throw Error();
}
}
}
1条答案
按热度按时间gr8qqesn1#
从您的代码片段来看,您似乎只在
ChatController
中的getChatsList()
函数中获取了一次聊天列表。然而,在实时聊天应用程序中,当新消息到达时,您需要侦听来自后端的更新。ChatController
中的方法getChatsList()
返回一个Stream
,但是您得到的是一个用async*
和yield
Package 的API调用的结果,当有新数据时,它不会自动更新。举一个实际的例子,我假设您正在使用Firebase,保持聊天实时更新的一种常见方法是使用
onValue
事件侦听器。当使用onValue
时,Firebase会在每次数据更改时自动调用您的回调函数,从而允许您的聊天实时更新。下面是一个如何使用它的例子:
在上面的示例中,将侦听器添加到特定聊天室的Firebase数据库引用中。对数据库中该位置的任何更改都将触发
onValue
事件并实时更新您的数据。这只是一个一般的例子。您必须根据特定的Firebase数据库结构调整数据库引用。
现在,由于我怀疑你使用的是Firebase或类似的实时数据库,而是REST API,因此实时更新更加复杂,可能涉及其他技术,如WebSocket,服务器发送事件(SSE)或推送通知。你需要检查你的后端是否支持这些。