이번에는 채팅 화면에 간단하게 메시지를 표시해 보겠습니다.
개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1
화면 구현은 아래와 같습니다.
./src/screens/chat/chatroom_screen.dart
class _ChatroomScreenState extends State<ChatroomScreen> {
late String chatroomKey;
final TextEditingController _textEditingController = TextEditingController();
late final ChatController chatController;
@override
void initState() {
// TODO: implement initState
chatroomKey = Get.parameters['chatroomKey']!;
chatController = Get.put(ChatController(chatroomKey));
super.initState();
}
@override
Widget build(BuildContext context) {
logger.d('${Get.parameters['chatroomKey']}');
UserModel1 userModel = UserController.to.userModel.value!;
List<ChatModel2> _chatList = ChatController.to.chatList;
Rxn<ChatroomModel2> chatModel = ChatController.to.chatroomModel;
return Scaffold(
appBar: AppBar(),
backgroundColor: Colors.grey[200],
// 화면 하단의 메뉴바 때문에 SafeArea 로 wrapping 해야 오동작을 방지함.
body: SafeArea(
child: Column(
children: [
// 게시글 정보를 간략히 표시
_buildItemInfo(context),
// 채팅 메시지 표시 부분
Expanded(
child: Obx(
() => Container(
color: Colors.yellowAccent,
child: ListView.separated(
shrinkWrap: true,
reverse: true,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
return ListTile(
dense: true,
title: Text(_chatList[index].msg +
' - ' +
DateFormat('yyyy-MM-dd').format(_chatList[index].createdDate)),
contentPadding: EdgeInsets.zero,
horizontalTitleGap: 0.0,
visualDensity: const VisualDensity(horizontal: 0, vertical: -4),
minVerticalPadding: 0,
);
},
separatorBuilder: (context, index) {
return const SizedBox(
height: 12,
);
},
itemCount: _chatList.length,
),
),
),
),
const Padding(padding: EdgeInsets.all(4)),
// 메시지 입력 창
_buildInputBar(userModel)
],
),
),
);
}
// 컬럼내부에 리스트타일(높이 관련 오류가 있어서 나중에 row+column 조함으로 변경함)과 버튼으로 구성 예정
MaterialBanner _buildItemInfo(BuildContext context) {
.... 중간생략
}
Widget _buildInputBar(UserModel1 userModel) {
.... 중간생략
}
}
./src/states/chat_controller.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../models/chat_model.dart';
import '../models/chatroom_model.dart';
import '../repo/chat_service.dart';
class ChatController extends GetxController {
static ChatController get to => Get.find();
final String _chatroomKey;
// 형선언을 직접해줘야 오류가 발생하지 않음
final RxList<ChatModel2> _chatList = <ChatModel2>[].obs;
final Rxn<ChatroomModel2> _chatroomModel = Rxn<ChatroomModel2>();
// 형선언을 직접해줘야 오류가 발생하지 않음
List<ChatModel2> get chatList => _chatList;
Rxn<ChatroomModel2> get chatroomModel => _chatroomModel;
@override
void onReady() {
// TODO: implement onReady
super.onReady();
debugPrint('************************* >>> ChatController >> onReady');
debugPrint('>>> ChatController >> onReady .. [$_chatroomKey]');
}
ChatController(this._chatroomKey) {
// todo: connect chatroom
ChatService().connectChatroom(_chatroomKey).listen((chatroomModel) {
// stream 처리해서 변경시 자동 호출됨
_chatroomModel.value = chatroomModel;
if (_chatList.isEmpty) {
// todo: fetch 10 latest chats, if chat list is empty
ChatService().getChatList(_chatroomKey).then((chatList) {
_chatList.addAll(chatList);
});
} else {
// todo: when new chatroom arrive, fetch latest chats
if (_chatList[0].reference == null) {
_chatList.removeAt(0);
}
ChatService().getLatestChats(_chatroomKey, _chatList[0].reference!).then((latestChats) {
_chatList.insertAll(0, latestChats);
});
}
});
}
}
'Flutter > 12 Clone 'Used Goods app'' 카테고리의 다른 글
[Flutter] Clone - 당근마켓53(Chat - 5) 동시 채팅 및 실제 정보 매핑 (0) | 2022.09.08 |
---|---|
[Flutter] Clone - 당근마켓52(Chat - 4) 메시지 스타일 (0) | 2022.09.07 |
[Flutter] Clone - 당근마켓50(Chat - 2) 상단/하단 정보 표시 (0) | 2022.09.02 |
[Flutter] Clone - 당근마켓49(Chat - 1) (1) | 2022.09.01 |
[Flutter] Clone - 당근마켓48(chatroomModel, chatModel) (0) | 2022.08.31 |