뷰 기반 디자인을 사용하는 기존 앱에 Compose 기반 UI를 추가할 수 있습니다.
전적으로 Compose에 기반하는 새로운 화면을 생성하려면 활동에서 setContent()
메서드를 호출하고 원하는 구성 가능한 함수를 전달하도록 합니다.
class ExampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // In here, we can call composables! MaterialTheme { Greeting(name = "compose") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
이 코드는 Compose 전용 앱에서 찾을 수 있는 코드와 비슷합니다.
ComposeView
ViewCompositionStrategy
ViewCompositionStrategy
는 컴포지션을 언제 폐기해야 하는지 정의합니다. 기본값인 ViewCompositionStrategy.Default
는 RecyclerView
과 같은 풀링 컨테이너의 일부가 아닌 한 기본 ComposeView
가 창에서 분리될 때 컴포지션을 삭제합니다. 단일 Activity Compose 전용 앱에서는 이 기본 동작이 바람직하지만 코드베이스에 Compose를 점진적으로 추가하는 경우 이 동작으로 인해 일부 시나리오에서 상태가 손실될 수 있습니다.
ViewCompositionStrategy
를 변경하려면 setViewCompositionStrategy()
메서드를 호출하고 다른 전략을 제공합니다.
아래 표에는 ViewCompositionStrategy
를 사용할 수 있는 다양한 시나리오가 요약되어 있습니다.
ViewCompositionStrategy |
설명 및 상호 운용성 시나리오 |
---|---|
DisposeOnDetachedFromWindow |
기본 ComposeView 가 창에서 분리되면 컴포지션이 삭제됩니다. 이후 DisposeOnDetachedFromWindowOrReleasedFromPool 로 대체되었습니다.상호 운용성 시나리오: * ComposeView 뷰 계층 구조의 유일한 요소인지 또는 혼합된 뷰/Compose 화면 (프래그먼트 아님)의 컨텍스트에 있는지 여부 |
DisposeOnDetachedFromWindowOrReleasedFromPool (기본값) |
DisposeOnDetachedFromWindow 와 마찬가지로 컴포지션이 풀링 컨테이너(예: RecyclerView )에 있지 않은 경우 풀링 컨테이너에 있는 경우 풀링 컨테이너 자체가 창에서 분리되거나 항목이 삭제될 때 (즉, 풀이 가득 찼을 때) 삭제됩니다.상호 운용성 시나리오: * ComposeView 뷰 계층 구조의 유일한 요소인지 또는 혼합된 뷰/Compose 화면의 컨텍스트에 있는지 (프래그먼트가 아님) 여부입니다.* ComposeView : RecyclerView 와 같은 풀링 컨테이너의 항목 |
DisposeOnLifecycleDestroyed |
제공된 Lifecycle 가 소멸되면 컴포지션이 삭제됩니다.상호 운용성 시나리오 * Fragment 뷰의 ComposeView |
DisposeOnViewTreeLifecycleDestroyed |
뷰가 연결된 다음 창의 ViewTreeLifecycleOwner.get 에서 반환된 LifecycleOwner 가 소유한 Lifecycle 가 소멸되면 컴포지션이 삭제됩니다.상호 운용성 시나리오: * 프래그먼트의 뷰에 있는 ComposeView .* 수명 주기가 아직 알려지지 않은 뷰의 ComposeView |
프래그먼트의 ComposeView
Compose UI 콘텐츠를 프래그먼트 또는 기존 뷰 레이아웃에 통합하려면 ComposeView
를 사용하고 setContent()
메서드를 호출합니다. ComposeView
는 Android View
입니다.
다음과 같이 다른 View
와 마찬가지로 ComposeView
를 XML 레이아웃에 배치할 수 있습니다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Kotlin 소스 코드에서 XML로 정의된 레이아웃 리소스의 레이아웃을 확장합니다. 그런 다음 XML ID를 사용하여 ComposeView
를 가져오고, 호스트 View
에 가장 적합한 컴포지션 전략을 설정한 다음, setContent()
를 호출하여 Compose를 사용합니다.
class ExampleFragmentXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.fragment_example, container, false) val composeView = view.findViewById<ComposeView>(R.id.compose_view) composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } }
또는 뷰 결합을 사용하여 XML 레이아웃 파일의 생성된 결합 클래스를 참조하여 ComposeView
참조를 가져올 수도 있습니다.
class ExampleFragment : Fragment() { private var _binding: FragmentExampleBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentExampleBinding.inflate(inflater, container, false) val view = binding.root binding.composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } override fun onDestroyView() { super.onDestroyView() _binding = null } }
그림 1. 뷰 UI 계층 구조에서 Compose 요소를 추가하는 코드의 출력을 보여줍니다. 'Hello Android!' 텍스트는 TextView
위젯에 의해 표시됩니다. 'Hello Compose!' 텍스트는 Compose 텍스트 요소에 의해 표시됩니다.
또한 전체 화면이 Compose를 사용하여 빌드된 경우 프래그먼트에 ComposeView
를 직접 포함할 수도 있습니다. 이렇게 하면 전적으로 XML 레이아웃 파일을 사용하지 않아도 됩니다.
class ExampleFragmentNoXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { MaterialTheme { // In Compose world Text("Hello Compose!") } } } } }
동일한 레이아웃의 여러 ComposeView
인스턴스
동일한 레이아웃에 ComposeView
요소가 여러 개 있다면 savedInstanceState
가 작동하기 위해서는 각 요소에 고유 ID가 있어야 합니다.
class ExampleFragmentMultipleComposeView : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = LinearLayout(requireContext()).apply { addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_x // ... } ) addView(TextView(requireContext())) addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_y // ... } ) } }
다음과 같이 ComposeView
ID는 res/values/ids.xml
파일에 정의되어 있습니다.
<resources> <item name="compose_view_x" type="id" /> <item name="compose_view_y" type="id" /> </resources>
Layout Editor에서 컴포저블 미리보기
ComposeView
가 포함된 XML 레이아웃의 Layout Editor 내에서 컴포저블을 미리 볼 수도 있습니다. 이렇게 하면 뷰와 Compose 레이아웃이 혼합된 컴포저블이 어떻게 표시되는지 확인할 수 있습니다.
레이아웃 편집기에 다음 구성 가능한 함수를 표시하려고 한다고 가정해 보겠습니다. @Preview
로 주석 처리된 컴포저블은 Layout Editor에서 미리보기에 적합합니다.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
이 컴포저블을 표시하려면 tools:composableName
도구 속성을 사용하고 레이아웃에서 미리 볼 컴포저블의 정규화된 이름으로 값을 설정합니다.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.compose.ui.platform.ComposeView android:id="@+id/my_compose_view" tools:composableName="com.example.compose.snippets.interop.InteroperabilityAPIsSnippetsKt.GreetingPreview" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout>
다음 단계
뷰에서 Compose를 사용하는 상호 운용성 API에 관해 알아보았으니 이제 Compose의 뷰의 사용법을 알아보세요.
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 기타 고려사항
- 이전 전략 {:#migration-strategy}
- Compose 및 뷰 실적 비교하기