First of all I don't know what i am facing, but I'll do my best to explain the situation.
I'm trying to build chat app and i have two sections on same page. These two different sections are rendering inside same ListView
. Only thing that changing is the data which i am using to feed the ListView
. I need to get the status of user in real time so i am putting tagged controllers for each tile which is rendering inside list view. Here comes the problem. The tiles rendered at the same index are not showing the true states of themselves until some state changes on that tile for example position of any Stack
item.
Here is the code.
In this part I'm rendering ListView
ListView.builder(
itemCount: chatController.currentChats!.length,
itemBuilder: (context, index) {
return GetBuilder<UserOnlineController>(
global: false,
init: Get.find<UserOnlineController>(tag: chatController.currentUserID == chatController.currentChats![index].user1 ? chatController.currentChats![index].user2 : chatController.currentChats![index].user1),
builder: (userController) {
return Stack(
children: [
Positioned(
child: Container(
color: Colors.black,
width: Get.width,
height: Dimensions.h100,
child: Center(
child: Text(
"${userController.user!.name!}",
style: TextStyle(
color: Colors.white
),
),
),
)
)
],
);
}
);
}),
This is the part that I'm putting controllers and listening chats in real time.
void listenChats() async {
var chatController = Get.find<ChatController>();
var messagesController = Get.find<MessagesController>();
String userID = Get.find<SharedPreferenceService>().getUserID();
var currentUserDoc = (await firestoreService.getCollection('users').where('userID', isEqualTo: userID).get()).docs[0];
Stream<DocumentSnapshot> userStream = firestoreService.getCollection('users').doc(currentUserDoc.id).snapshots();
Stream<QuerySnapshot> chatStream = firestoreService.getCollection('chats').snapshots();
await for(var user in userStream){
var userObject = UserModel.fromJson(user.data() as Map<String,dynamic>);
await for(var chats in chatStream) {
List<Chat> activeChats = [];
List<Chat> unActiveChats = [];
List<Chat> newMatches = [];
List<Chat> allChats = [];
var filteredChats = chats.docs.where((chat) => userObject.chat!.active_chats!.contains(chat['chatID'])).toList();
filteredChats.forEach((chatDoc) {
var currentChat = Chat.fromJson(chatDoc.data() as Map<String,dynamic>);
if(currentChat.user1 == userID){
Get.put(
UserOnlineController(firestoreService: firestoreService, userID: currentChat.user2!),
tag: currentChat.user2!,
);
}
else{
Get.put(
UserOnlineController(firestoreService: firestoreService, userID: currentChat.user1!),
tag: currentChat.user1!
);
}
allChats.add(currentChat);
if(currentChat.isActive!){
if(currentChat.isStarted!){
activeChats.add(currentChat);
}
else{
newMatches.add(currentChat);
}
}
else{
unActiveChats.add(currentChat);
}
});
messagesController.generatePositions(activeChats.length, true);
messagesController.generatePositions(unActiveChats.length, false);
chatController.setAllChats(allChats);
chatController.setCurrentChats();
chatController.setChats(activeChats, unActiveChats, newMatches);
}
}
}
And this is the part that I'm using to control the UI state
void setAllChats(List<Chat> allChats) {
_allChats = allChats;
}
void setCurrentChats() {
_currentChats = _allChats!.where((chat) => chat.isActive! == isActiveMessages).toList();
update();
}
void setIsActiveMessages(bool state){
_isActiveMessages = state;
_currentChats = _allChats!.where((chat) => chat.isActive! == state).toList();
update();
}
In the above pictures all of these users are different but only true one is the third one at second screen shot.
Hello again this question basically explains all the details. Multiple Instance with GetX tag not working in flutter
Basically you need to add key parameter.
GetBuilder<UserChatController>(
key: Key(currentUserControllerTag),
tag: currentUserControllerTag,
global: false,
init: Get.find<UserChatController>(tag: currentUserControllerTag),
builder: (controller) {
return controller.user != null ? Container(
width: Get.width,
height: Dimensions.h100,
child: Stack(
children: [
Positioned(
left: 0,
right: 0,
child: Container(
height: Dimensions.h100,
width: double.maxFinite,
color: Colors.black,
child:Center(
child: Text(
controller.user != null ? controller.user!.name! : "",
style: TextStyle(
color: Colors.white
),
),
)
))
],
),
) : Container();
},
)