Oluşturmada Görünümleri Kullanma

Compose kullanıcı arayüzüne Android görünüm hiyerarşisi ekleyebilirsiniz. Bu yaklaşım, özellikle Beste'de henüz kullanıma sunulmamış kullanıcı arayüzü öğelerini (ör. AdView) kullanmak istediğinizde yararlıdır. Bu yaklaşım, tasarlamış olabileceğiniz özel görünümleri yeniden kullanmanıza da olanak tanır.

Bir görünüm öğesi veya hiyerarşi eklemek için AndroidView composable'ı kullanın. AndroidView işlevine View döndüren bir lambda iletilir. AndroidView ayrıca görünüm şişirildiğinde çağrılan bir update geri çağırma da sağlar. Geri çağırma işlevi içinde okunan bir State her değiştiğinde AndroidView yeniden oluşturulur. 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 { mutableIntStateOf(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()
    }
}

AndroidView ile bağlama görüntüleme

XML düzeni yerleştirmek için androidx.compose.ui:ui-viewbinding kitaplığı tarafından sağlanan AndroidViewBinding API'sini kullanın. Bunu yapmak için projenizde view binding'in etkinleştirilmesi gerekir.

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

Lazy Lists'te AndroidView

Lazy list'te (LazyColumn, LazyRow, Pager vb.) AndroidView kullanıyorsanız 1.4.0-rc01 sürümünde kullanıma sunulan AndroidView aşırı yüklemesini kullanmayı düşünebilirsiniz. Bu aşırı yükleme, kapsayan kompozisyon olduğu gibi yeniden kullanıldığında (Lazy listelerdeki gibi) Compose'un temel View örneğini yeniden kullanmasına olanak tanır.

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

  • onReset: View öğesinin yeniden kullanılmak üzere olduğunu bildirmek için çağrılan geri çağırma. Görünümün yeniden kullanılmasını sağlamak için bu değer boş olmamalıdır.
  • onRelease (isteğe bağlı): View öğesinin kompozisyondan çıktığını ve tekrar kullanılmayacağını bildirmek için çağrılan bir geri çağırma.

@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()
                }
            )
        }
    }
}

Compose'da parçalar

Compose'da Fragment eklemek için AndroidFragment composable'ı kullanın. AndroidFragment, composable, kompozisyondan ayrıldığında parçayı kaldırma gibi parçaya özel işleme sahiptir.

Bir parçayı dahil etmek için AndroidFragment composable'ı kullanın. Fragment sınıfını AndroidFragment'ye aktarırsınız. AndroidFragment, bu sınıfın bir örneğini doğrudan kompozisyona ekler. AndroidFragment ayrıca, belirli bir durumla AndroidFragment oluşturmak için fragmentState nesnesi, yeni parçaya iletilecek arguments ve kompozisyondaki parçayı sağlayan bir onUpdate geri çağırma işlevi de sağlar. Diğer birçok yerleşik composable gibi AndroidFragment da, örneğin üst composable'daki konumunu ayarlamak için kullanabileceğiniz bir Modifier parametresini kabul eder.

Oluşturma bölümünde AndroidFragment işlevini aşağıdaki şekilde kullanın:

@Composable
fun FragmentInComposeExample() {
    AndroidFragment<MyFragment>()
}

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

Compose, Android çerçeve sınıfları içinde ç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 framework sınıflarını kullanabilir.

Sistem kaynakları hakkında daha fazla bilgi edinmek için Compose'daki kaynaklar başlıklı makaleyi inceleyin.

Composition Locals

CompositionLocal sınıfları, verilerin oluşturulabilir işlevler aracılığıyla örtülü olarak iletilmesine olanak tanır. Genellikle kullanıcı arayüzü ağacının belirli bir düğümünde değerle birlikte sağlanır. Bu değer, CompositionLocal'yı composable işlevinde parametre olarak bildirmeden composable alt öğeleri tarafından kullanılabilir.

CompositionLocal, Compose'da Context, Configuration veya Compose kodunun barındırıldığı View gibi Android çerçeve türlerinin değerlerini ilgili LocalContext, LocalConfiguration veya LocalView ile yaymak için kullanılır. CompositionLocal sınıflarının, IDE'de otomatik tamamlama ile daha iyi bulunabilmesi için Local önekiyle başladığını unutmayın.

CompositionLocal öğesinin geçerli değerine current özelliği kullanılarak erişilir. Örneğin, aşağıdaki kodda Toast.makeToast yöntemine LocalContext.current sağlanarak bir kısa ileti gösterilmektedir.

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

Yayın alıcılar

CompositionLocal ve yan etkileri göstermek için, bir BroadcastReceiver'ın composable işlevinden kaydedilmesi gerekiyorsa geçerli bağlamı kullanmak için LocalContext, rememberUpdatedState ve DisposableEffect yan etkileri kullanılmalıdı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 */
}

Diğer etkileşimler

İhtiyacınız olan etkileşim için tanımlanmış bir yardımcı program yoksa en iyi uygulama, genel Compose yönergesini izlemektir: Veriler aşağı, etkinlikler yukarı akar (Compose'da Düşünme bölümünde daha ayrıntılı olarak ele alınmıştır). Örneğin, bu composable farklı bir etkinliği 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)
    }
}