画面遷移:NavHost - Ki-Kobayashi/Android-Wiki GitHub Wiki

🟩 画面遷移は一元管理

MainActivity.kt -> 💡MyApp.kt (👈で管理する)

【手順】

  1. MyApp.ktを作成し、MainActivity.kt から呼ぶ
  2. NavHostの準備
  3. 各画面 Composable の関係性を書く

.

🟡 MainActivity.kt

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            JetTodo2Theme {
                // A surface container using the 'background' color from the theme
                MyApp(Modifier.fillMaxSize())
            }
        }
    }
}

.

🟡 MyApp.kt

🚨ポイント🚨

  • composable("/") の「"/"」箇所(Path)は、別ファイルで一元管理すると良さそう(下記サンプルはハード)
  • ViewModelを渡すのも、「MyApp.kt(NavHost定義箇所)」で一元管理する
  • onBackなどの画面遷移に関わるアクションも、コールバックとして「MyApp.kt(NavHost定義箇所)」で一元管理する

.
以下は、上記の下2つを満たすコード例。

.

package com.example.jettodo2

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.jettodo2.presenter.screen.CreateTaskScreen
import com.example.jettodo2.presenter.screen.EditTaskScreen
import com.example.jettodo2.presenter.screen.TaskListScreen
import com.example.jettodo2.presenter.viewmodel.CreateTaskViewModel
import com.example.jettodo2.presenter.viewmodel.EditTaskViewModel
import com.example.jettodo2.presenter.viewmodel.TaskListViewModel

// TODO:スナックバーの表示(非同期で実行される)

@Composable
fun MyApp(modifier: Modifier) {
    // 💡1💡 Navを追加するには、以下のように書く
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "/") {
        composable("/") {
            val vm: TaskListViewModel = hiltViewModel()
            TaskListScreen(
                viewModel = vm,
                toCreateTaskScreen = {
                    navController.navigate("/create")
                },
                // 💡2💡【遷移時に値をPathで渡す方法】: シンプルな値のみ(API取得に使用するKeyなど)
                onClickListRow = { id ->
                    navController.navigate("/tasks/$id")
                }
            )
        }
        composable("/create") {
            val vm: CreateTaskViewModel = hiltViewModel()
            CreateTaskScreen(
                viewModel = vm,
                onBack = {
                    navController.popBackStack()
                }
            )
        }
        composable(
            "/tasks/{taskId}",
            // 💡3💡【遷移時に値をnavArgumentで渡す方法】シンプルな値に限る(取得に必要なデータのみ渡すようにする)
            arguments = listOf(
                navArgument("taskId") {
                    type = NavType.LongType
                }
            )
        ) {
            val vm: EditTaskViewModel = hiltViewModel()
            EditTaskScreen(
                viewModel = vm,
                back = { navController.popBackStack() },
            )
        }
    }
}

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.

🟩

🟡

.