[Flutter] 블로그 만들기 - 게시글 모델링

2025. 2. 11. 13:36·Flutter/App
728x90

📌 이번 글에서는 PostListPage를 구성하고, AutoDisposeNotifier를 사용하여 게시글 목록을 효율적으로 관리하는 방법을 다룹니다.
게시글을 불러오고, 리스트를 렌더링하며, 사용자 경험을 개선하기 위해 PostListItem을 활용합니다.
또한, 뷰모델을 AutoDisposeNotifier로 구현하여 불필요한 상태 유지 및 메모리 누수를 방지하는 방법을 살펴봅니다.


1️⃣ 게시글 모델링 (User, Post, PostList)

📌 User 모델

게시글의 작성자를 나타내는 모델입니다.

// 게시글 주인이 누구인가? --> User 모델 정의
// 인증 여부는 SessionUser 로 진행할 예정
class User {
  int? id;
  String? username;
  String? imgUrl;

  User.fromMap(Map<String, dynamic> map)
      : id = map["id"],
        username = map["username"],
        imgUrl = map["imgUrl"];
}

 

✔ User 정보를 불러와서 게시글과 연결


📌 Post 모델

게시글 하나에 대한 정보를 담는 모델입니다.

import 'package:intl/intl.dart';
import 'user.dart';

class Post {
  int? id;
  String? title;
  String? content;
  DateTime? createdAt;
  DateTime? updatedAt;
  int? bookmarkCount;
  bool? isBookmark;
  User? user;

  Post.fromMap(Map<String, dynamic> map)
      : id = map["id"],
        title = map["title"],
        content = map["content"],
        createdAt = DateFormat("yyyy-MM-dd").parse(map["createdAt"]),
        updatedAt = DateFormat("yyyy-MM-dd").parse(map["updatedAt"]),
        bookmarkCount = map["bookmarkCount"],
        isBookmark = map["isBookmark"],
        user = User.fromMap(map["user"]);
}
 

✔ 게시글 제목, 내용, 작성일, 북마크 수, 유저 정보를 포함


📌 PostList 모델

게시글 목록을 한 페이지 단위로 관리하는 모델입니다.

import 'package:class_f_story/data/model/post.dart';

class PostList {
  bool isFirst;
  bool isLast;
  int pageNumber;
  int size;
  int totalPage;
  List<Post> posts;

  PostList({
    required this.isFirst,
    required this.isLast,
    required this.pageNumber,
    required this.size,
    required this.totalPage,
    required this.posts,
  });

  // 팩토리 생성자를 활용하여 JSON 데이터를 객체로 변환
  factory PostList.fromMap(Map<String, dynamic> map) {
    return PostList(
      isFirst: map['isFirst'] ?? false,
      isLast: map['isLast'] ?? false,
      pageNumber: map['pageNumber'] ?? 0,
      size: map['size'] ?? 10,
      totalPage: map['totalPage'] ?? 1,
      posts: (map['posts'] as List<dynamic>? ?? [])
          .map((e) => Post.fromMap(e))
          .toList(),
    );
  }

  // 깊은 복사 (객체 변경 시 활용)
  PostList copyWith({
    bool? isFirst,
    bool? isLast,
    int? pageNumber,
    int? size,
    int? totalPage,
    List<Post>? posts,
  }) {
    return PostList(
      isFirst: isFirst ?? this.isFirst,
      isLast: isLast ?? this.isLast,
      pageNumber: pageNumber ?? this.pageNumber,
      size: size ?? this.size,
      totalPage: totalPage ?? this.totalPage,
      posts: posts ?? List<Post>.from(this.posts), // 리스트 깊은 복사
    );
  }
}

 

✔ 페이지네이션을 지원하는 PostList 모델


2️⃣ PostListPage 구현

게시글 목록을 표시하는 페이지입니다.

import 'package:class_f_story/ui/pages/post/list_page/widgets/post_list_body_temp.dart';
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'),
        ),
        body: PostListBodyTemp(),
      ),
    );
  }
}

 

✔ Drawer를 포함한 기본적인 PostListPage 레이아웃 구성


3️⃣ PostListItem 구현

각 게시글 항목을 표시하는 위젯입니다.

import 'package:flutter/material.dart';
import '../../../../../_core/utils/m_http.dart';
import '../../../../../data/model/post.dart';

class PostListItem extends StatelessWidget {
  Post post;

  PostListItem(this.post);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text("${post.title}", style: TextStyle(fontWeight: FontWeight.bold)),
      subtitle: Text(
        "${post.content}",
        style: TextStyle(color: Colors.black45),
        overflow: TextOverflow.ellipsis,
        maxLines: 1,
      ),
      trailing: ClipRRect(
        borderRadius: BorderRadius.circular(50),
        child: Image.asset('assets${post.user!.imgUrl}'),
      ),
    );
  }
}

 

✔ 게시글 제목, 내용, 유저 프로필 이미지 표시


4️⃣ PostListViewModel (AutoDisposeNotifier 적용)

뷰모델을 AutoDisposeNotifier로 구현하여 불필요한 상태 유지 및 메모리 누수 방지

import 'package:class_f_story/_core/utils/exception_handler.dart';
import 'package:class_f_story/data/model/post_list.dart';
import 'package:class_f_story/data/repository/post_repository.dart';
import 'package:class_f_story/main.dart';
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../../_core/utils/logger.dart';

class PostListViewModel extends AutoDisposeNotifier<PostList?> {
  final refreshController = RefreshController();
  final postRepository = const PostRepository();
  final mContext = navigatorkey.currentContext!;

  @override
  PostList? build() {
    logger.d('PostListViewModel 초기화 완료');

    // AutoDisposeNotifier가 메모리에서 내려갈 때 콜백 실행
    ref.onDispose(() {
      refreshController.dispose();
    });

    init();
    return null;
  }

  Future<void> init() async {
    try {
      Map<String, dynamic> resBody = await postRepository.findAll();
      if (!resBody['success']) {
        ExceptionHandler.handleException(
            resBody['errorMessage'], StackTrace.current);
        return;
      }

      state = PostList.fromMap(resBody);
      refreshController.loadComplete();
    } catch (e, stackTrace) {
      ExceptionHandler.handleException('게시글 불러오기 오류', stackTrace);
    }
  }
}

 

✔ AutoDisposeNotifier 적용하여 메모리 관리 최적화

✔ 게시글 목록 API 요청 및 상태 관리


✅ 마무리: 구현된 기능 정리

✔ Post, PostList, User 모델을 정의하여 게시글 데이터 관리
✔ PostListPage 및 PostListItem을 생성하여 게시글 목록 UI 구성
✔ AutoDisposeNotifier를 적용한 PostListViewModel을 활용하여 메모리 누수 방지 및 상태 관리 최적화
✔ refreshController를 사용하여 새로고침 및 추가 데이터 로드 기능 구현

 

🚀 이번 글에서는 게시글 목록을 효과적으로 관리하기 위해 PostListPage와 AutoDisposeNotifier 적용 방법을 살펴보았습니다.
이제 게시글 목록을 더 효율적으로 관리하고, 최적화된 상태 유지 및 메모리 관리까지 가능해졌습니다! 🎯

'Flutter > App' 카테고리의 다른 글

[Flutter] 블로그 만들기 - pull_to_refresh 라이브러리 사용  (0) 2025.02.11
[Flutter] 블로그 만들기 - 게시글 작성 기능 구현  (0) 2025.02.10
[Flutter] 블로그 만들기 - 게시글 관리 및 로그아웃 기능 구현  (0) 2025.02.10
[Flutter] 블로그 만들기 -자동 로그인 기능 구현 및 UI  (0) 2025.02.10
[Flutter] 블로그 만들기 - 회원가입 기능 구현 및 UI  (1) 2025.02.09
'Flutter/App' 카테고리의 다른 글
  • [Flutter] 블로그 만들기 - pull_to_refresh 라이브러리 사용
  • [Flutter] 블로그 만들기 - 게시글 작성 기능 구현
  • [Flutter] 블로그 만들기 - 게시글 관리 및 로그아웃 기능 구현
  • [Flutter] 블로그 만들기 -자동 로그인 기능 구현 및 UI
공돌이 출신 개발자
공돌이 출신 개발자
공돌이 출신 개발자입니다
  • 공돌이 출신 개발자
    공돌이 출신 개발자
    공돌이 출신 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (124)
      • Database (0)
        • SQL (0)
        • 1일 1쿼리 (9)
      • Flutter (40)
        • Dart 언어 (18)
        • App (22)
      • Git (0)
      • Http 기초 지식 (14)
      • HTML5 & CSS3 (0)
      • Java (33)
      • JSP (0)
      • JavaScript (0)
      • Linux (0)
      • MSA (0)
      • Project (0)
      • React (0)
      • Spring (19)
      • 설치 메뉴얼 (1)
      • [Flutter] 프로젝트 (눈길) (8)
        • 작업일지 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    flutter
    객체
    Java
    공부
    데이터
    spring boot
    객체지향
    android studio
    회원가입
    로그인
    dart
    앱개발
    jsp
    안드로이드 앱 개발
    프로젝트
    앱 개발
    1일1쿼리
    SQL
    클래스
    코딩
    안드로이드
    SQLD
    개발
    메서드
    블로그 만들기
    JAVA 기초
    HTTP
    플러터
    Android
    프로그래밍
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
공돌이 출신 개발자
[Flutter] 블로그 만들기 - 게시글 모델링
상단으로

티스토리툴바