1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Androidアプリ】メモ編集機能 - 基本設計書 (改訂版)

Last updated at Posted at 2025-10-02

1. はじめに

ChatGPT Image 2025年10月2日 10_34_27.png

本ドキュメントは、「メモ編集機能 要件定義書」に基づき、機能を実現するための基本的な設計を定義するものである。

2. 設計方針

  • アーキテクチャ: 既存のMVVMアーキテクチャを踏襲します。UI(Compose)、ViewModel、Repository、Local DataSource(Room)の責務を明確に分離します。
  • UI実装: UIの構築はすべてJetpack Composeで行い、Fragmentは使用しません。
  • 画面遷移: 画面間のナビゲーションは Navigation Compose ライブラリを用いて実装します。
  • エラーハンドリング: DB操作の失敗など、ユーザーに通知すべきエラーはSnackbarを用いて表示します。ViewModelからUIへは、既存のUiEventの仕組みを流用して通知し、UI全体で一貫したエラー体験を提供します。

3. 画面設計

3.1. 画面一覧

画面ID 画面名 ファイル名 責務
SC-001 メモ一覧画面 MemoListScreen.kt 保存されているメモを更新日時順に一覧表示する。
SC-002 メモ詳細・編集画面 MemoDetailScreen.kt 新規メモ作成既存メモ編集の両方の機能を提供する。

3.2. ナビゲーショングラフ

  • 画面遷移の定義: MemoDetailScreenは、渡されるmemoIdの値によって「新規作成モード」と「編集モード」を切り替えます。
  • memoIdの規約:
    • memoId > 0: 編集モード
    • memoId = -1L: 新規作成モード
  • MemoListScreen -> MemoDetailScreen
    • 【編集フロー】:
      • 遷移トリガー: メモリストのアイテムをタップする。
      • 受け渡す引数: memoId: Long (タップされたメモの実ID)。
    • 【新規作成フロー】:
      • 遷移トリガー: 画面右下のFloatingActionButtonをタップする。
      • 受け渡す引数: memoId: Long = -1L (新規作成を示す固定値)。
  • MemoDetailScreen -> MemoListScreen
    • 遷移トリガー:
      1. 保存アイコンをタップし、DB更新/追加が成功した後。
      2. 画面左上の戻るアイコン、またはシステムの「戻る」ナビゲーションを実行した時。

3.3. 各画面の詳細設計

3.3.1. メモ一覧画面 (MemoListScreen)
  • レイアウト:
    • TopAppBar: アプリ名を表示。
    • LazyColumn: メモのリストを縦方向にスクロール表示。各アイテムにはメモの「タイトル」と「更新日時」を表示する。
    • FloatingActionButton: memoId = -1Lを引数としてMemoDetailScreenへ遷移するための「+」ボタン。
    • MemoInputSectionは本改修で削除する
  • 表示項目:
    • メモのタイトル
    • メモの更新日時
  • 操作:
    • メモアイテムのタップ: MemoDetailScreen へ遷移する(引数:memoId)。
    • FABのタップ: MemoDetailScreen へ遷移する(引数:-1L)。
3.3.2. メモ詳細・編集画面 (MemoDetailScreen)
  • レイアウト:
    • TopAppBar:
      • 左端に「←」アイコン(一覧画面へ戻る)。
      • 右端に「保存」アイコン。
    • コンテンツエリア:
      • タイトル入力用の TextField
      • 本文入力用の TextField(複数行入力可)。
  • 状態管理:
    • ViewModelは画面初期化時に渡されたmemoIdをチェックします。
    • memoId > 0の場合:DBから該当メモを取得し、タイトルと内容をTextFieldに表示します。
    • memoId = -1Lの場合:TextFieldを空の状態で表示します。
    • 「保存」アイコンは、タイトルまたは本文に変更があった場合のみ活性化(クリック可能)させます。
  • 操作:
    • 「←」アイコンタップ: 変更を破棄して一覧画面へ戻ります。
    • 「保存」アイコンタップ: MemoDetailViewModel の保存処理を呼び出します。成功したら一覧画面へ戻り、失敗時はSnackbarでエラーを表示します。

4. データ設計

4.1. ER図

4.2. テーブル定義(data/model/Memo.kt

要件に基づき、titleupdatedAt カラムを Memo エンティティに追加します。

カラム名 データ型 説明 制約
id Long メモID Primary Key, Auto Increment
title String メモのタイトル Not Null
content String メモの内容 Not Null
createdAt LocalDateTime 作成日時 Not Null
updatedAt LocalDateTime 更新日時 Not Null

4.3. データベースマイグレーション

既存のテーブルスキーマに変更が加わるため、Roomの Migration を実装する必要があります。

  • バージョン: 1 -> 2
  • 変更内容: memos テーブルに title (TEXT) と updatedAt (INTEGER) カラムを追加する。

5. コンポーネント設計 (MVVM)

5.1. ViewModel

  • MemoListViewModel.kt (既存のMemoViewModelから改名)
    • 責務: メモの一覧を取得し、UIに公開します。
    • 主なロジック: memoRepository.getMemos() を監視し、MemoUiState としてUIに公開します。
  • MemoDetailViewModel.kt (新規作成)
    • 責務: 単一のメモの状態管理。渡された memoId に応じて、新規作成モードと編集モードの処理(データ取得、保存/更新)を分岐させる
    • 保持する状態:
      • メモのID、タイトル、内容
      • UIの状態(ローディング、成功、エラーなど)
    • 公開するメソッド:
      • onTitleChange(title: String): タイトルの変更をハンドルする。
      • onContentChange(content: String): 内容の変更をハンドルする。
      • saveMemo(): memoIdを判定し、新規追加 (addMemo) または更新 (updateMemo) を実行する。

5.2. Repository

  • MemoRepository.kt
    • 追加するメソッド:
      • getMemoById(id: Long): Flow: 指定されたIDのメモを1件取得する。
      • updateMemo(memo: Memo): 既存のメモを更新する。

5.3. DAO

  • MemoDao.kt
    • 変更・追加するメソッド:
      • @Query("SELECT * FROM memos ORDER BY updatedAt DESC"): getAllMemos() のクエリを更新日時順に変更する。
      • @Query("SELECT * FROM memos WHERE id = :id"): getMemoById(id: Long): Flow を追加する。
      • @Update: updateMemo(memo: Memo) を追加する。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?