티스토리 뷰
✅ 채팅 화면
1️⃣ 채팅방 기본 세팅
① 채팅방 파일 만들기 ( chat_room_screen.dart )
import 'package:flutter/material.dart';
class ChatRoomScreen extends StatefulWidget {
const ChatRoomScreen({Key? key}) : super(key: key);
@override
State<ChatRoomScreen> createState() => _ChatRoomScreenState();
}
class _ChatRoomScreenState extends State<ChatRoomScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("ChatRoomScreen"),
),
);
}
}
② 채팅목록에 탭 이벤트 넣기 ( chat_card.dart )
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChatRoomScreen(),
));
},
2️⃣ 배경 및 앱바 만들기
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class ChatRoomScreen extends StatefulWidget {
const ChatRoomScreen({Key? key}) : super(key: key);
@override
State<ChatRoomScreen> createState() => _ChatRoomScreenState();
}
class _ChatRoomScreenState extends State<ChatRoomScreen> {
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xffb2c7da),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
title: Text(
"홍길동",
style: Theme.of(context).textTheme.headline6,
),
actions: [
Icon(FontAwesomeIcons.search, size: 20),
SizedBox(width: 25),
Icon(FontAwesomeIcons.bars, size: 20),
SizedBox(width: 25),
],
),
),
);
}
}
- Scaffold가 컨테이너의 배경을 가리면 안되므로, transparent(투명색) 처리함.
3️⃣ TimeLine 위젯 컴포넌트 만들기
import 'package:flutter/material.dart';
class TimeLine extends StatelessWidget {
const TimeLine({Key? key, required this.time}) : super(key: key);
final String time;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Color(0xff9cafbe),
),
child: Text(
time,
style: TextStyle(color: Colors.white),
),
);
}
}
4️⃣ TimeLine 위젯 채팅방 화면에 띄우기
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
TimeLine(time: "2021년 1월 1일 금요일"),
],
),
),
),
],
),
➡ width가 TimeLine 만큼만 잡혀있기 때문에 좌측에 쏠려 있음. 추후 Column의 width가 늘어나게 되면 자동으로 위치 정렬됨!
🔎 SingleChildScrollView + Column
- Column으로 나열한 위젯이 작은 화면에서 넘치는 것을 방지하기 위해 사용
- 가운데 정렬해서 사용하는 로그인 화면 등에서 사용할 수 있는 기법
➡ 단순히 정가운데 배치를 하고 싶은 경우에는 SingleChildScrollView를 Center 위젯으로 감싸주어야 함!
5️⃣ 상대방이 작성한 채팅 위젯 만들기 - 컴포넌트
import 'package:flutter/material.dart';
import 'package:flutter_kakao/models/user.dart';
class OtherChat extends StatelessWidget {
const OtherChat(
{Key? key, required this.name, required this.text, required this.time})
: super(key: key);
final String name;
final String text;
final String time;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(friends[0].backgroundImage),
),
SizedBox(width: 10),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(name),
Container(
child: Text(text),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(13),
color: Colors.white,
),
),
],
),
),
SizedBox(width: 5),
Text(
time,
style: TextStyle(fontSize: 12),
),
],
),
);
}
}
6️⃣ 내가 작성한 채팅 위젯 만들기 - 컴포넌트
import 'package:flutter/material.dart';
class MyChat extends StatelessWidget {
const MyChat({Key? key, required this.text, required this.time})
: super(key: key);
final String text;
final String time;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
time,
style: TextStyle(fontSize: 12),
),
SizedBox(width: 5),
Flexible(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(13),
color: Color(0xfffeec34),
),
child: Text(text),
),
),
],
);
}
}
7️⃣ 작성한 채팅 위젯 화면에 구현하기
final List<MyChat> chats = [];
final TextEditingController _textController = TextEditingController();
...
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
TimeLine(time: "2021년 1월 1일 금요일"),
OtherChat(
name: "홍길동",
text: "새해 복 많이 받으세요.",
time: "오전 10:10"),
MyChat(text: "선생님도 많이 받으십시오.", time: "오후 2:15"),
...List.generate(chats.length, (index) => chats[index]),
],
),
),
),
),
],
),
...List.generate(chats.length, (index) => chats[index]) 이후 만들 채팅 입력 UI를 이용하여 chats에 새 글이 추가되면 화면에 나열하기
8️⃣ 채팅 입력 UI 만들기
① 채팅 입력 아이콘
import 'package:flutter/material.dart';
class ChatIconButton extends StatelessWidget {
const ChatIconButton({Key? key, required this.icon}) : super(key: key);
final Icon icon;
@override
Widget build(BuildContext context) {
return IconButton(
padding: EdgeInsets.symmetric(horizontal: 15),
onPressed: () {},
icon: icon,
iconSize: 25,
);
}
}
② 채팅 입력창 UI
final TextEditingController _textController = TextEditingController();
...
Container(
height: 60,
color: Colors.white,
child: Row(
children: [
ChatIconButton(icon: Icon(FontAwesomeIcons.plusSquare)),
Expanded(
child: Container(
child: TextField(
controller: _textController,
maxLines: 1,
style: TextStyle(fontSize: 20),
decoration: InputDecoration(
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
),
),
),
ChatIconButton(icon: Icon(FontAwesomeIcons.smile)),
ChatIconButton(icon: Icon(FontAwesomeIcons.cog)),
],
),
),
- InputDecoration : html의 input창을 스타일링 하는 위젯
🔎 TextEditingController
: 텍스트필드에 입력된 텍스트의 변화를 감지하고 핸들링 하는 방법 ➡ 인스턴스에 핸들링 함수를 리스너로 등록
③ submit 이벤트 함수 만들기 (글을 입력하고 완료 버튼을 누르면 입력창에 글을 비워줌)
void _handleSubmitted(text) {
_textController.clear();
setState(() {
chats.add(
MyChat(
text: text,
time: DateFormat("a K:m")
.format(new DateTime.now())
.replaceAll("AM", "오전")
.replaceAll("PM", "오후"),
),
);
});
}
- _textController.clear()로 내가 입력한 글을 비워줌
- setState를 이용하여 새로 작성한 글을 chats에 추가함과 동시에 화면에 그려지도록 함
🔎 DateFormat ( intl package )
- 원하는 형태로 시간, 날짜, 요일을 표현할 수 있음
- format 메소드에 DateTime을 넣어주면 formatted string을 구할 수 있음
- new DateTime.now() = 현재 시간, 날짜, 요일 가져오기
a = 오전/오후
h = 시 (K로 해도 시간이 나오네...?)
m = 분
s = 초
EEEE = 요일
yyy = 년
MMM = 월
d = 일
[chat_room_screen.dart 전체코드]
import 'package:flutter/material.dart';
import 'package:flutter_kakao/components/chat_icon_button.dart';
import 'package:flutter_kakao/components/other_chat.dart';
import 'package:flutter_kakao/components/time_line.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import '../components/my_chat.dart';
class ChatRoomScreen extends StatefulWidget {
const ChatRoomScreen({Key? key}) : super(key: key);
@override
State<ChatRoomScreen> createState() => _ChatRoomScreenState();
}
class _ChatRoomScreenState extends State<ChatRoomScreen> {
final List<MyChat> chats = [];
final TextEditingController _textController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Color(0xffb2c7da),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
title: Text(
"홍길동",
style: Theme.of(context).textTheme.headline6,
),
actions: [
Icon(FontAwesomeIcons.search, size: 20),
SizedBox(width: 25),
Icon(FontAwesomeIcons.bars, size: 20),
SizedBox(width: 25),
],
),
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
TimeLine(time: "2021년 1월 1일 금요일"),
OtherChat(
name: "홍길동",
text: "새해 복 많이 받으세요.",
time: "오전 10:10"),
MyChat(text: "선생님도 많이 받으십시오.", time: "오후 2:15"),
...List.generate(chats.length, (index) => chats[index]),
],
),
),
),
),
Container(
height: 60,
color: Colors.white,
child: Row(
children: [
ChatIconButton(icon: Icon(FontAwesomeIcons.plusSquare)),
Expanded(
child: Container(
child: TextField(
controller: _textController,
maxLines: 1,
style: TextStyle(fontSize: 20),
decoration: InputDecoration(
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
onSubmitted: _handleSubmitted,
),
),
),
ChatIconButton(icon: Icon(FontAwesomeIcons.smile)),
ChatIconButton(icon: Icon(FontAwesomeIcons.cog)),
],
),
),
],
),
),
),
);
}
void _handleSubmitted(text) {
_textController.clear();
setState(() {
chats.add(
MyChat(
text: text,
time: DateFormat("a K:m")
.format(new DateTime.now())
.replaceAll("AM", "오전")
.replaceAll("PM", "오후"),
),
);
});
}
}
'- flutter' 카테고리의 다른 글
flutter - Riverpod 라이브러리 (0) | 2022.11.15 |
---|---|
kakao앱 만들기 (6) - 더보기 화면 (0) | 2022.11.11 |
kakao앱 만들기 (4) - 채팅리스트 화면 (0) | 2022.11.11 |
kakao앱 만들기 (3) - 프로필 화면 (0) | 2022.11.11 |
kakao앱 만들기 (2) - 친구 목록 화면 (0) | 2022.11.11 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 네트워크로딩
- styled-components
- Riverpod
- firestore
- hooks
- 리액트
- 플러터
- props
- 비동기
- 채팅리스트
- Filter
- react
- 리액트문법
- map
- 네트워크데이터
- State
- Provider
- useState
- GestureDetector
- RadioList
- table-calendar
- Flutter
- 주사위게임
- 모두의숙소
- 웹만들기
- 정렬변경
- sort메서드
- appbar
- throtting
- 글쓰기
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함