Oluşturmada Görünümleri Kullanma

Bir Android Görünümü hiyerarşisini Oluşturma kullanıcı arayüzüne ekleyebilirsiniz. Bu yaklaşım, AdView gibi henüz Oluştur'da bulunmayan kullanıcı arayüzü öğelerini kullanmak istiyorsanız özellikle 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 kompozitini kullanın. AndroidView, View döndüren bir lambda işlevi alır. AndroidView, görünüm şişirildiğinde çağrılan bir update geri çağırması da sağlar. Geri çağırma işlevi içinde okunan bir State değiştiğinde AndroidView yeniden oluşturulur. Diğer birçok yerleşik bileşen gibi AndroidView de Modifier parametresi alır. Bu parametre, örneğin üst bileşendeki konumunu ayarlamak için kullanılabilir.

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

AndroidView görüntü bağlama ile

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

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

AndroidView in Lazy lists

Tembel bir listede AndroidView (LazyColumn, LazyRow, Pager vb.) kullanıyorsanız 1.4.0-rc01 sürümünde kullanıma sunulan AndroidViewaşırı yüklemeyi kullanmayı düşünebilirsiniz. Bu aşırı yükleme, Compose'un, içeren kompozisyon yeniden kullanıldığında temel View örneğini yeniden kullanmasına olanak tanır. Bu durum, tembel listelerde olduğu gibidir.

AndroidView işlevinin bu aşırı yüklemesi 2 ek parametre ekler:

  • onReset: View öğesinin yeniden kullanılacağını bildirmek için çağrılan geri çağırma işlevi. Görünümü yeniden kullanmayı 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 işlevi.

@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ştur'daki parçalar

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

Bunu, Fragment için tutucu olarak FragmentContainerView içeren bir XML şişirerek yapabilirsiniz.

Örneğin, my_fragment_layout.xml tanımlanmışsa android:name XML özelliğini Fragment sınıfınızın adıyla değiştirirken aşağıdaki 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" />

Oluştur'da bu parçayı aşağıdaki gibi genişletin:

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

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

Oluştur, 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 çerçeve sınıflarını kullanabilir.

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

Besteciler

CompositionLocal sınıfları, composable işlevler üzerinden verilerin dolaylı olarak geçirilmesini sağlar. Genellikle kullanıcı arayüzü ağacının belirli bir düğümünde bir değerle sağlanır. Bu değer, CompositionLocal öğesini composable işlevinde parametre olarak tanımlamadan composable alt öğeleri tarafından kullanılabilir.

CompositionLocal, Compose'da Android çerçevesi türleri (ör. Context, Configuration veya View) için değerleri ilgili LocalContext, LocalConfiguration veya LocalView ile birlikte dağıtmak amacıyla kullanılır. IDE'de otomatik tamamlama özelliğiyle daha iyi bulunabilirlik için CompositionLocal sınıflarının başına Local eklendiğini unutmayın.

Bir CompositionLocal öğesinin current özelliğini kullanarak mevcut değerine erişin. Örneğin, aşağıdaki kodda Toast.makeToast yöntemine LocalContext.current sağlanarak bir durum mesajı gösterilmektedir.

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

Daha kapsamlı bir örnek için bu dokümanın sonundaki Örnek Olay: BroadcastReceivers bölümüne göz atın.

Diğer etkileşimler

İhtiyacınız olan etkileşim için tanımlanmış bir yardımcı yoksa en iyi uygulama, genel oluşturma kurallarına uymaktır. Bu kural, verilerin akan, etkinliklerin yukarı akışıdır (Yazma'da Düşünme bölümünde ayrıntılı olarak 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'a taşımak veya uygulamak isteyebileceğiniz özelliklerle ilgili daha gerçekçi bir örnek ve CompositionLocal ile yan etkileri göstermek için bir derlenebilir işlevden BroadcastReceiver kaydetmeniz gerektiğini varsayalım.

Çözüm, mevcut bağlamı kullanmak için LocalContext, rememberUpdatedState ve DisposableEffect yan etkileri kullanı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

Görünümlerde Oluştur'u kullanırken ve bunun tersi durumda birlikte çalışabilirlik API'lerini bildiğinize göre, daha fazla bilgi edinmek için Diğer hususlar sayfasını inceleyin.