[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
  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

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

티스토리툴바