대화 레시피

이 레시피에서는 대화상자로 대상을 표시하는 방법을 보여줍니다.

작동 방식

대화상자로 목적지를 표시하려면 다음 두 가지 작업을 실행해야 합니다.

  1. DialogSceneStrategy 사용: DialogSceneStrategy 인스턴스를 만들고 NavDisplay 컴포저블의 sceneStrategy 매개변수에 전달합니다.

  2. 대상에 메타데이터 추가: 대화상자로 표시할 대상의 메타데이터에 DialogSceneStrategy.dialog()를 추가합니다. 이 작업은 entry 함수에서 수행됩니다. DialogProperties 객체를 전달하여 대화상자의 동작과 모양을 맞춤설정할 수도 있습니다.

이 예시에서는 RouteB이 대화상자로 구성됩니다. RouteA에서 RouteB로 이동하면 RouteB이 대화상자 창에 표시됩니다.

대화상자의 콘텐츠는 필요에 따라 스타일을 지정할 수 있습니다. 이 레시피에서는 콘텐츠가 둥근 모서리로 클리핑됩니다.

자세한 내용은 맞춤 레이아웃에 관한 공식 문서를 참고하세요.

/*
 * Copyright 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.nav3recipes.dialog

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.compose.dropUnlessResumed
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.scene.DialogSceneStrategy
import androidx.navigation3.ui.NavDisplay
import com.example.nav3recipes.content.ContentBlue
import com.example.nav3recipes.content.ContentGreen
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
import kotlinx.serialization.Serializable

@Serializable
private data object RouteA : NavKey

@Serializable
private data class RouteB(val id: String) : NavKey

class DialogActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        setEdgeToEdgeConfig()
        super.onCreate(savedInstanceState)
        setContent {
            val backStack = rememberNavBackStack(RouteA)
            val dialogStrategy = remember { DialogSceneStrategy<NavKey>() }

            NavDisplay(
                backStack = backStack,
                onBack = { backStack.removeLastOrNull() },
                sceneStrategies = listOf(dialogStrategy),
                entryProvider = entryProvider {
                    entry<RouteA> {
                        ContentGreen("Welcome to Nav3") {
                            Button(onClick = dropUnlessResumed {
                                backStack.add(RouteB("123"))
                            }) {
                                Text("Click to open dialog")
                            }
                        }
                    }
                    entry<RouteB>(
                        metadata = DialogSceneStrategy.dialog(
                            DialogProperties(windowTitle = "Route B dialog")
                        )
                    ) { key ->
                        ContentBlue(
                            title = "Route id: ${key.id}",
                            modifier = Modifier.clip(
                                shape = RoundedCornerShape(16.dp)
                            )
                        )
                    }
                }
            )
        }
    }
}