0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【超入門】ごちゃごちゃ`MainActivity`から卒業!Jetpack Composeのナビゲーションを綺麗に整理する技

Posted at

Jetpack Composeで開発を進めていると、MainActivity.ktにあれもこれもとコードが増えてきて、気づけば「秘伝のタレ」のような巨大なファイルになっていませんか?

特に、画面遷移を管理する**NavHostは、画面が増えるたびにどんどん長くなりがちです**。

この記事では、そんなMainActivityをスッキリさせ、プロジェクトの見通しを劇的に良くする簡単なリファクタリング術をご紹介します。

なぜ整理が必要? 現状:MainActivityが駅と路線図を兼任している状態

Composeを学び始めると、多くの場合MainActivityNavHostを直接書きます。これは、小さなアプリなら問題ありません。

❌ 整理前のコード (MainActivity.kt)

画面遷移の定義がMainActivityの中に直接書かれており、非常に読みにくい状態です。

class MainActivity : ComponentActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContent {
            SimpleMemoAppAndroidTheme {
                val navController = rememberNavController()
                
                // MainActivityの中に直接、画面遷移の定義が書かれている
                NavHost(navController = navController, startDestination = "memo_list") {
                    composable("memo_list") { MemoListScreen(navController) }
                    composable("memo_detail/{memoId}") { DetailScreen(navController) }
                    
                    // ...画面が10個になったら、ここがすごく長くなる...
                }
            }
        }
    }
}

これをに例えてみましょう。MainActivityはアプリの入口なので「駅舎」です。NavHostは、どの電車がどのホームに来るかを定義する「路線図」です。今の状態は、駅舎の壁に、巨大な路線図が直接ペンキで描かれているようなものです。

【問題点】

  • 駅舎の役割が多すぎる: 「建物の管理」と「路線図の管理」という2つの仕事が混ざっている。
  • 見通しが悪い: 路線図の全体像を把握しにくい。
  • メンテナンスが大変: 「路線図を修正したいだけなのに、駅舎全体の工事図面を開かないといけない」のは面倒。

解決策:路線図を「総合案内所」へお引越し!

ごちゃごちゃした壁の路線図を消して、代わりに**「総合案内所」を新設**し、そこに綺麗な路線図を設置しましょう。駅舎は「総合案内所はこちらです」と案内するだけになり、とてもスッキリします。

手順1:「総合案内所」の場所を作る

navigationという名前の新しい置き場所(パッケージ)を作ります。

  1. Android Studioでuiパッケージなどを右クリック
  2. New > Package を選択
  3. navigation と入力して作成

手順2:「総合案内所」のファイルを作り、路線図を設置する

作成したnavigationパッケージの中に、AppNavHost.ktというファイルを作り、MainActivityからNavHostの部分を丸ごと引っ越してきます。

ui/navigation/AppNavHost.kt (新しく作るファイル)

このファイルは、画面遷移の管理だけに責任を持つ、専門家になりました。

package com.example.simplememoapp_android.navigation // 新しい住所

import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.simplememoapp_android.ui.screen.MemoDetailScreen
import com.example.simplememoapp_android.ui.screen.MemoListScreen

// これが「路線図」の本体!
@Composable
fun AppNavHost(navController: NavHostController) {
    NavHost(navController = navController, startDestination = "memo_list") {
        
        // 「メモ一覧」行きホーム
        composable("memo_list") {
            MemoListScreen(navController = navController)
        }
        
        // 「メモ詳細」行きホーム
        composable("memo_detail/{memoId}") { backStackEntry ->
            MemoDetailScreen(
                navController = navController,
                backStackEntry = backStackEntry
            )
        }
    }
}

手順3:「駅舎」をスッキリさせる

最後に、MainActivityからペンキの路線図を消して、「総合案内所を見てね」と案内するだけのシンプルな形に修正します。

MainActivity.kt (修正後)

MainActivityの責務は「アプリを起動すること」だけになり、とても見通しが良くなりました。

import com.example.simplememoapp_android.navigation.AppNavHost // 総合案内所をインポート

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContent {
            SimpleMemoAppAndroidTheme {
                val navController = rememberNavController()

                // 総合案内所(AppNavHost)を呼び出すだけ!超スッキリ!
                AppNavHost(navController = navController)
            }
        }
    }
}

これで完了です!


登場人物紹介!ナビゲーションの主要メンバー

今回の整理で使った3人の主要メンバーを、改めて紹介します。

NavController (電車の運転士 👨‍✈️)

  • 役割: 実際に画面から画面へと連れて行ってくれる運転士です。「次はこの駅へ行け!」「一つ前の駅に戻れ!」と命令します。
  • 呼び出し方: val navController = rememberNavController()
  • 命令の仕方: navController.navigate("駅の名前")navController.popBackStack()

NavHost (路線図 🗺️)

  • 役割: アプリ内の全ての駅(画面)と、駅間の繋がりを定義した路線図です。startDestinationで、最初にどの駅に停車するかを指定します。
  • 使い方: AppNavHost.ktに設置し、中に各駅のホーム(composable)を定義します。

composable("駅の名前") (駅のホーム 🚉)

  • 役割: 路線図に描かれた、一つ一つの駅のホームです。"memo_list"という名前のホームにはMemoListScreenが、"memo_detail/{memoId}"という名前のホームにはMemoDetailScreenが来ます。
  • {memoId}のように{}で囲むと、「IDカード」などの**切符(引数)**を受け取ることができます。

まとめ

MainActivityがごちゃごちゃしてきたら、それはリファクタリングの良いサインです。

今回のように、責務(役割)ごとにファイルを分割するだけで、コードは驚くほどクリーンで、未来のあなたが読んでも理解しやすいプロフェッショナルな状態になります。

ぜひ、あなたのプロジェクトでも試してみてください!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?