장면 데코레이터를 사용하면 앱의 장면 전략에 따라 계산된 장면을 수정할 수 있습니다. 결과적으로 NavDisplay에 의해 표시되는 콘텐츠를 구성하는 두 번째 단계에 사용됩니다.
이 접근 방식을 사용하면 일반적인 UI 구성요소 표시와 같은 특정 기능을 개별 장면 데코레이터로 캡슐화할 수 있습니다.
예를 들어 이메일 받은편지함, 채팅 메시지 받은편지함, 캘린더 보기라는 세 개의 최상위 경로가 있는 생산성 앱을 생각해 보세요. 이러한 앱은 두 개의 장면 데코레이터를 사용할 수 있습니다. 하나는 현재 최상위 경로의 정보와 컨트롤을 표시하는 상단 앱 바를 추가하는 데 사용되고 다른 하나는 경로 간에 탐색할 수 있는 영구 탐색 메뉴나 레일을 추가하는 데 사용됩니다.
장면 데코레이터 전략 만들기
장면 데코레이터는 장면 전략과 유사한 패턴을 따릅니다. 장면 데코레이터를 정의하려면 SceneDecoratorStrategy 인터페이스를 구현합니다. 이 인터페이스에는 SceneStrategy 인터페이스의 calculateScene 메서드와 유사한 decorateScene 메서드가 있습니다.
decorateScene는 장면을 장식할 수 있는지 여부를 결정합니다.
- 장면 데코레이터 전략이 입력 장면을 데코레이션하지 않아야 하는 경우 입력 장면을 그대로 반환합니다.
- 입력 장면을 데코레이션해야 하는 경우 새
Scene를 반환합니다. 일반적으로 반환된 장면은 입력 장면을 매개변수로 사용하고 자체content메서드 내에서 입력 장면의content메서드를 호출합니다.
입력 장면을 장식해야 하는지 여부와 방법을 결정하기 위해 장면 장식기 전략은 입력 Scene와 해당 장면 내에 포함된 항목의 메타데이터를 모두 고려할 수 있습니다.
class MySceneDecoratorStrategy<T : Any> : SceneDecoratorStrategy<T> { override fun SceneDecoratorStrategyScope<T>.decorateScene(scene: Scene<T>): Scene<T> { // `shouldDecorate` determines if the scene should be decorated based on scene.metadata, // scene.entries.metadata, or any other relevant state. return if (shouldDecorate(scene)) { MyDecoratingScene(scene) } else { scene } } } class MyDecoratingScene<T : Any>(scene: Scene<T>) : Scene<T> { // ... override val content = @Composable { scene.content() } }
장면 데코레이터 전략 사용
장면 데코레이터 전략을 사용하려면 sceneDecoratorStrategies 매개변수를 사용하여 NavDisplay에 제공하세요. 장면을 데코레이션할 때 NavDisplay는 각 전략의 decorateScene 메서드를 연속으로 호출하여 각 호출의 출력을 다음 호출의 입력으로 전달합니다.
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
장면 데코레이터의 일반적인 패턴
장면 데코레이터를 구현할 때 다음은 알아야 할 몇 가지 일반적인 패턴입니다.
속성 복사
많은 경우 장면을 데코레이션하여 반환된 장면에는 데코레이션하는 장면과 동일한 항목이 포함되어야 하며 이전 항목도 동일해야 합니다. 또한 기본 동작을 사용하는 대신 장식하는 장면의 메타데이터를 상속 (또는 수정)해야 합니다. 다음 코드는 이 작업을 수행하는 방법을 보여주는 예시입니다.
class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
애니메이션 유지
대상 간 애니메이션 처리에 설명된 대로 NavDisplay는 현재 장면의 클래스와 key 속성에서 파생된 키가 변경될 때 장면 간 전환을 자동으로 애니메이션 처리합니다.
앱에 장면 데코레이터를 도입할 때 장면 데코레이션 후에 반환되는 장면의 클래스는 장면 계산 중에 반환되는 장면의 클래스가 변경되더라도 동일하게 유지될 수 있습니다. 이러한 상황에서 장면을 데코레이션하는 장면이 데코레이션하는 장면의 key를 직접 복사하면 파생된 키가 변경되지 않으므로 내장 애니메이션이 더 이상 발생하지 않습니다.
기본 제공 애니메이션 지원을 유지하려면 장면을 데코레이션할 때 클래스에서 파생되고 calculateScene에서 반환된 장면의 key에서 파생된 키를 사용해야 합니다.
class DerivedKeyScene<T : Any>(scene: Scene<T>) : Scene<T> { override val key = scene::class to scene.key // ... }