Oluşturmada Görünümleri Kullanma

Oluşturma kullanıcı arayüzüne Android Görünümü hiyerarşisi ekleyebilirsiniz. Bu yaklaşım özellikle, AdView gibi henüz Oluşturma'da kullanılamayan kullanıcı arayüzü öğelerini kullanmak istediğinizde kullanışlıdır. Bu yaklaşım, tasarlamış olabileceğiniz özel görünümleri yeniden kullanmanıza da olanak tanır.

Görünüm öğesi veya hiyerarşi eklemek için AndroidView composable'ı kullanın. AndroidView, View döndüren bir lambda geçirilir. AndroidView, görünüm büyütüldüğünde çağrılan bir update geri çağırması da sağlar. AndroidView, geri çağırma içindeki bir State okuma işlemi değiştiğinde yeniden oluşturur. AndroidView, diğer birçok yerleşik composable gibi, örneğin üst composable'daki konumunu ayarlamak için kullanılabilecek bir Modifier parametresi alır.

@Composable
fun CustomView() {
    var selectedItem by remember { mutableStateOf(0) }

    // Adds view to Compose
    AndroidView(
        modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
        factory = { context ->
            // Creates view
            MyView(context).apply {
                // Sets up listeners for View -> Compose communication
                setOnClickListener {
                    selectedItem = 1
                }
            }
        },
        update = { view ->
            // View's been inflated or state read in this block has been updated
            // Add logic here if necessary

            // As selectedItem is read here, AndroidView will recompose
            // whenever the state changes
            // Example of Compose -> View communication
            view.selectedItem = selectedItem
        }
    )
}

@Composable
fun ContentExample() {
    Column(Modifier.fillMaxSize()) {
        Text("Look at this CustomView!")
        CustomView()
    }
}

Görünüm bağlamalı AndroidView

XML düzeni yerleştirmek için androidx.compose.ui:ui-viewbinding kitaplığı tarafından sağlanan AndroidViewBinding API'yi kullanın. Bunun için projenizde görünüm bağlamayı etkinleştirmelisiniz.

@Composable
fun AndroidViewBindingExample() {
    AndroidViewBinding(ExampleLayoutBinding::inflate) {
        exampleView.setBackgroundColor(Color.GRAY)
    }
}

Tembel listelerde AndroidView

Geç listede bir AndroidView (LazyColumn, LazyRow, Pager vb.) kullanıyorsanız 1.4.0-rc01 sürümünde ortaya çıkan AndroidView aşırı yükünü kullanmayı düşünün. Bu aşırı yükleme, Compose'un içeren beste geç listelerde olduğu gibi yeniden kullanıldığında temel View örneğini yeniden kullanmasına izin verir.

Bu AndroidView aşırı yüklemesi 2 ek parametre ekler:

  • onReset - View öğesinin yeniden kullanılmak üzere olduğunu belirtmek için çağrılan geri çağırma. Görünümün yeniden kullanımını etkinleştirmek için bu değer boş olmamalıdır.
  • onRelease (isteğe bağlı) - View öğesinin besteden çıktığını ve tekrar kullanılmayacağını belirtmek için çağrılan geri çağırma.

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun AndroidViewInLazyList() {
    LazyColumn {
        items(100) { index ->
            AndroidView(
                modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree
                factory = { context ->
                    MyView(context)
                },
                update = { view ->
                    view.selectedItem = index
                },
                onReset = { view ->
                    view.clear()
                }
            )
        }
    }
}

Oluşturma işleminde parçalar

Oluştur'a Fragment eklemek için AndroidViewBinding composable'ı kullanın. AndroidViewBinding, composable besteden ayrıldığında parçanın kaldırılması gibi parçaya özgü işlemlere sahiptir.

Bunu, Fragment öğesinin tutucusu olarak FragmentContainerView içeren bir XML'i şişirerek yapın.

Örneğin, my_fragment_layout.xml tanımladıysanız android:name XML özelliğini Fragment sınıf adınızla değiştirirken şunun gibi bir kod kullanabilirsiniz:

<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.compose.snippets.interop.MyFragment" />

Bu parçayı Compose'da şu şekilde şişirin:

@Composable
fun FragmentInComposeExample() {
    AndroidViewBinding(MyFragmentLayoutBinding::inflate) {
        val myFragment = fragmentContainerView.getFragment<MyFragment>()
        // ...
    }
}

Aynı düzende birden fazla parça kullanmanız gerekiyorsa her FragmentContainerView için benzersiz bir kimlik tanımladığınızdan emin olun.

Compose'dan Android çerçevesini çağırma

Compose, Android çerçeve sınıflarında çalışır. Örneğin, Activity veya Fragment gibi Android View sınıflarında barındırılır ve Context, sistem kaynakları, Service veya BroadcastReceiver gibi Android çerçeve sınıflarını kullanabilir.

Sistem kaynakları hakkında daha fazla bilgi edinmek için Oluşturma işlevindeki kaynaklar başlıklı makaleyi inceleyin.

Beste Yereller

CompositionLocal sınıfları, composable işlevler üzerinden verilerin dolaylı olarak aktarılmasını sağlar. Bunlara genellikle kullanıcı arayüzü ağacının belirli bir düğümünde bir değer verilir. Bu değer, CompositionLocal öğesi composable işlevde parametre olarak tanımlanmadan composable alt öğeleri tarafından kullanılabilir.

CompositionLocal, Compose'daki Context, Configuration veya Compose kodunun karşılık gelen LocalContext, LocalConfiguration veya LocalView ile barındırıldığı View gibi Android çerçeve türlerinin değerlerini yaymak için kullanılır. IDE'de otomatik tamamlamayla daha kolay keşfedilebilmesi için CompositionLocal sınıflarının önüne Local eklendiğini unutmayın.

current özelliğini kullanarak bir CompositionLocal öğesinin geçerli değerine erişin. Örneğin aşağıdaki kod, Toast.makeToast yöntemine LocalContext.current sağlayarak bir durum mesajı mesajı gösterir.

@Composable
fun ToastGreetingButton(greeting: String) {
    val context = LocalContext.current
    Button(onClick = {
        Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show()
    }) {
        Text("Greet")
    }
}

Daha eksiksiz bir örnek için bu belgenin sonundaki Örnek Olay: BroadcastRecipientrs bölümüne göz atın.

Diğer etkileşimler

İhtiyaç duyduğunuz etkileşim için tanımlanmış bir yardımcı program yoksa en iyi uygulama, genel Oluşturma yönergelerini uygulamaktır: Veriler aşağı iner, etkinlikler aktarılır (Thinking in Compose'da daha ayrıntılı bir şekilde anlatılmıştır). Örneğin, bu composable farklı bir etkinlik başlatır:

class OtherInteractionsActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // get data from savedInstanceState
        setContent {
            MaterialTheme {
                ExampleComposable(data, onButtonClick = {
                    startActivity(Intent(this, MyActivity::class.java))
                })
            }
        }
    }
}

@Composable
fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) {
    Button(onClick = onButtonClick) {
        Text(data.title)
    }
}

Örnek olay: Yayın alıcıları

Compose'da taşımak veya uygulamak isteyebileceğiniz özelliklere daha gerçekçi bir örnek vermek ve CompositionLocal ile yan efektleri göstermek için bir BroadcastReceiver öğesinin composable bir işlevden kaydedilmesi gerektiğini varsayalım.

Çözüm, mevcut bağlamı ve rememberUpdatedState ile DisposableEffect yan etkilerini kullanmak için LocalContext'den faydalanır.

@Composable
fun SystemBroadcastReceiver(
    systemAction: String,
    onSystemEvent: (intent: Intent?) -> Unit
) {
    // Grab the current context in this part of the UI tree
    val context = LocalContext.current

    // Safely use the latest onSystemEvent lambda passed to the function
    val currentOnSystemEvent by rememberUpdatedState(onSystemEvent)

    // If either context or systemAction changes, unregister and register again
    DisposableEffect(context, systemAction) {
        val intentFilter = IntentFilter(systemAction)
        val broadcast = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                currentOnSystemEvent(intent)
            }
        }

        context.registerReceiver(broadcast, intentFilter)

        // When the effect leaves the Composition, remove the callback
        onDispose {
            context.unregisterReceiver(broadcast)
        }
    }
}

@Composable
fun HomeScreen() {

    SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus ->
        val isCharging = /* Get from batteryStatus ... */ true
        /* Do something if the device is charging */
    }

    /* Rest of the HomeScreen */
}

Sonraki adımlar

Artık Görünümler'de Oluşturma API'lerini kullanırken ve bunun tersini kullanırken birlikte çalışabilirlik API'lerini bildiğinize göre daha fazla bilgi edinmek için Dikkat edilmesi gereken diğer noktalar sayfasını inceleyin.