Görünümler'de Oluşturma'yı kullanma

Görünüm tabanlı bir tasarım kullanan mevcut bir uygulamaya Compose tabanlı kullanıcı arayüzü ekleyebilirsiniz.

Tamamen Compose tabanlı yeni bir ekran oluşturmak için etkinliğinizin setContent() yöntemini çağırmasını ve istediğiniz composable işlevlerini iletmesini sağlayın.

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!")
}

Bu kod, yalnızca Compose'un kullanıldığı bir uygulamada bulacağınız koda benzer.

ComposeView için ViewCompositionStrategy

ViewCompositionStrategy Composition'ın ne zaman kaldırılması gerektiğini tanımlar. Varsayılan olan, ViewCompositionStrategy.Default, temel alınan ComposeView pencereden ayrıldığında, RecyclerView gibi bir havuz kapsayıcısının parçası olmadığı sürece Composition'ı kaldırır. Yalnızca tek bir etkinlik içeren ve yalnızca Compose kullanılan bir uygulamada bu varsayılan davranış istenen bir durumdur. Ancak kod tabanınıza kademeli olarak Compose ekliyorsanız bu davranış bazı senaryolarda durum kaybına neden olabilir.

ViewCompositionStrategy değerini değiştirmek için setViewCompositionStrategy() yöntemini çağırın ve farklı bir strateji sağlayın.

Aşağıdaki tabloda, ViewCompositionStrategy kullanabileceğiniz farklı senaryolar özetlenmektedir:

ViewCompositionStrategy Açıklama ve birlikte çalışabilirlik senaryosu
DisposeOnDetachedFromWindow Temel alınan ComposeView pencereden ayrıldığında Composition nesnesi silinir. Bu işlev, DisposeOnDetachedFromWindowOrReleasedFromPool ile değiştirilmiştir.

Birlikte çalışabilirlik senaryosu:

* ComposeView Görünüm hiyerarşisindeki tek öğe mi yoksa karma Görünüm/Compose ekranı bağlamında mı (Parça'da değil) kullanılıyor?
DisposeOnDetachedFromWindowOrReleasedFromPool (Varsayılan) DisposeOnDetachedFromWindow'ya benzer şekilde, beste RecyclerView gibi bir havuz kapsayıcısında olmadığında. Bir havuzlama kapsayıcısında bulunuyorsa havuzlama kapsayıcısının pencereden ayrılması veya öğenin atılması (ör. havuz dolduğunda) durumunda atılır.

Birlikte çalışabilirlik senaryosu:

* ComposeViewGörünüm hiyerarşisindeki tek öğe mi yoksa karma Görünüm/Oluşturma ekranı bağlamında mı (Parça'da değil) kullanılıyor?
* ComposeView gibi bir havuz kapsayıcısında öğe olarak RecyclerView.
DisposeOnLifecycleDestroyed Sağlanan Lifecycle yok edildiğinde Composition da yok edilir.

Interop senaryosu

* ComposeView in a Fragment's View.
DisposeOnViewTreeLifecycleDestroyed View'in bağlı olduğu bir sonraki pencerenin ViewTreeLifecycleOwner.get tarafından döndürülen LifecycleOwner öğesine ait Lifecycle yok edildiğinde Composition kaldırılır.

Interop senaryosu:

* Fragment'ın View'inde ComposeView.
* Yaşam döngüsünün henüz bilinmediği bir görünümde ComposeView

Parçalarda ComposeView (Geçiş Adımı)

Compose UI içeriğini bir parçaya veya mevcut bir View düzenine dahil etmek istiyorsanız ComposeView kullanın ve setContent() yöntemini çağırın. ComposeView, Android View.

ComposeView öğesini, diğer View öğeleri gibi XML düzeninize yerleştirebilirsiniz:

<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 kaynak kodunda, XML'de tanımlanan layout resource öğesinden düzeni genişletin. Ardından XML kimliğini kullanarak ComposeView alın, ana makine için en uygun olan bir Composition stratejisi belirleyin View ve Compose'u kullanmak için setContent() çağrısı yapın.

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

Alternatif olarak, XML düzen dosyanız için oluşturulan bağlama sınıfına başvurarak ComposeView öğesine referans almak üzere görünüm bağlamayı da kullanabilirsiniz:

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

Birbiri üzerinde bulunan, biraz farklı iki metin öğesi

Şekil 1. Bu, View kullanıcı arayüzü hiyerarşisine Compose öğeleri ekleyen kodun çıktısını gösterir. "Hello Android!" metni bir TextView widget'ı tarafından gösteriliyor. "Hello Compose!" metni, bir Compose metin öğesi tarafından gösterilir.

Tam ekranınız Compose ile oluşturulmuşsa doğrudan bir parçaya ComposeView ekleyerek XML düzen dosyası kullanmaktan tamamen kaçınabilirsiniz.

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!")
                }
            }
        }
    }
}

Aynı düzende birden fazla ComposeView örneği

Aynı düzende birden fazla ComposeView öğesi varsa savedInstanceState öğesinin çalışması için her birinin benzersiz bir kimliği olması gerekir.

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 kimlikleri res/values/ids.xml dosyasında tanımlanır:

<resources>
  <item name="compose_view_x" type="id" />
  <item name="compose_view_y" type="id" />
</resources>

Layout Editor'da composable'ları önizleme

Ayrıca, ComposeView içeren XML düzeniniz için Layout Editor'da composable'ları önizleyebilirsiniz. Bu sayede, composable'larınızın karma Görünümler ve Compose düzeninde nasıl göründüğünü görebilirsiniz.

Düzen Düzenleyici'de aşağıdaki composable'ı görüntülemek istediğinizi varsayalım. @Preview ile ek açıklama eklenmiş composable'ların, Layout Editor'da önizleme için uygun olduğunu unutmayın.

@Preview
@Composable
fun GreetingPreview() {
    Greeting(name = "Android")
}

Bu composable'ı görüntülemek için tools:composableName tools özelliğini kullanın ve değerini, düzende önizlenecek composable'ın tam nitelikli adıyla ayarlayın.

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

Düzen düzenleyicide gösterilen composable