Flutter 앱에서 게시글을 관리하기 위해 PostRepository를 만들고, 이를 활용한 PostListPage를 구현하는 과정에 대해 다룹니다. 또한, 사용자 로그인 및 로그아웃 처리를 위한 CustomDrawer까지 설명합니다.
1. PostRepository 구현하기
게시글 데이터를 서버와 연동하기 위해 PostRepository를 작성합니다.
이를 통해 게시글 조회, 생성, 수정, 삭제 등의 기능을 제공합니다.
PostRepository의 역할
- 게시글 목록 조회 (findAll)
→ 페이지 번호를 입력받아 해당 페이지의 게시글을 서버에서 가져옵니다. - 게시글 상세 조회 (findById)
→ 특정 게시글의 ID를 이용해 상세 정보를 가져옵니다. - 게시글 삭제 (delete)
→ 특정 ID를 가진 게시글을 삭제합니다. - 게시글 생성 (save)
→ 새로운 게시글을 생성하고 서버에 저장합니다. - 게시글 수정 (update)
→ 기존 게시글을 수정하여 서버에 반영합니다.
class PostRepository {
const PostRepository();
// 게시글 목록 조회
Future<Map<String, dynamic>> findAll({int page = 0}) async {
Response response = await dio.get('/api/post', queryParameters: {'page': page});
return response.data;
}
// 게시글 상세 조회
Future<Map<String, dynamic>> findById({required int id}) async {
Response response = await dio.get('/api/post/$id');
return response.data;
}
// 게시글 삭제
Future<Map<String, dynamic>> delete({required int id}) async {
Response response = await dio.delete('/api/post/$id');
return response.data;
}
// 게시글 생성
Future<Map<String, dynamic>> save(Map<String, dynamic> reqData) async {
Response response = await dio.post('/api/post', data: reqData);
return response.data;
}
// 게시글 수정
Future<Map<String, dynamic>> update(int id, Map<String, dynamic> reqData) async {
Response response = await dio.put('/api/post/$id', data: reqData);
return response.data;
}
}
2. PostListPage 만들기
이제 게시글 목록을 표시하는 PostListPage를 구현합니다.
PostListPage의 역할
- Drawer와 연결하여 사용자 메뉴 제공
- 게시글 목록을 보여주는 UI 작성
import 'package:class_f_story/ui/widgets/custom_drawer.dart';
import 'package:flutter/material.dart';
class PostListPage extends StatelessWidget {
final scaffoldKey = GlobalKey<ScaffoldState>();
PostListPage({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: scaffoldKey,
drawer: CustomDrawer(scaffoldKey),
appBar: AppBar(
title: Text('f-story'),
),
),
);
}
}
3. CustomDrawer를 활용한 로그아웃 기능
사용자가 로그인된 상태에서 로그아웃할 수 있도록 CustomDrawer에 로그아웃 버튼을 추가합니다.
import 'package:class_f_story/data/gvm/session_gvm.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class CustomDrawer extends ConsumerWidget {
final GlobalKey<ScaffoldState> scaffoldKey;
const CustomDrawer(this.scaffoldKey, {super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
SessionGVM vm = ref.read(sessionProvider.notifier);
return Container(
width: 250,
color: Colors.white,
child: Column(
children: [
TextButton(
onPressed: () {
scaffoldKey.currentState!.openEndDrawer();
Navigator.pushNamed(context, 'post/write');
},
child: Text('글쓰기'),
),
Divider(),
TextButton(
onPressed: () async {
await vm.logout();
},
child: Text('로그아웃'),
),
Divider(),
],
),
);
}
}
4. PostWritePage 구현
게시글을 작성할 수 있는 화면을 추가합니다.
UI 컴포넌트 분리
- CustomTextFormField (단일 줄 입력)
- CustomTextArea (여러 줄 입력)
- CustomElevatedButton (버튼)
PostWritePage 구성
import 'package:class_f_story/ui/pages/post/write_page/widgets/post_write_body.dart';
import 'package:flutter/material.dart';
class PostWritePage extends StatelessWidget {
const PostWritePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: PostWriteBody(),
);
}
}
PostWriteBody (UI 레이아웃)
import 'package:class_f_story/ui/pages/post/write_page/widgets/post_write_form.dart';
import 'package:flutter/material.dart';
class PostWriteBody extends StatelessWidget {
const PostWriteBody({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Flexible(
child: PostWriteForm(),
),
],
),
);
}
}
PostWriteForm (게시글 입력 및 저장 버튼)
import 'package:class_f_story/ui/widgets/custom_elevated_button.dart';
import 'package:class_f_story/ui/widgets/custom_text_area.dart';
import 'package:class_f_story/ui/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PostWriteForm extends ConsumerWidget {
final _titleController = TextEditingController();
final _contentController = TextEditingController();
PostWriteForm({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Form(
child: ListView(
shrinkWrap: true,
children: [
CustomTextFormField(hint: '제목', controller: _titleController),
SizedBox(height: 10),
CustomTextArea(hint: '내용', controller: _contentController),
SizedBox(height: 20),
CustomElevatedButton(
text: '작성 완료',
click: () {
// 게시글 저장 로직 추가 예정
},
)
],
),
);
}
}
정리
- PostRepository를 통해 게시글 CRUD API와 연동
- PostListPage를 만들어 게시글 목록을 표시
- CustomDrawer를 활용하여 로그아웃 기능 추가
- PostWritePage를 구현하여 사용자가 게시글을 작성할 수 있도록 구성