E-posta oluşturma ve diğer kitaplıklar

Compose'da favori kitaplıklarınızı kullanabilirsiniz. Bu bölümde en yararlı kitaplıklardan birkaçının nasıl ekleneceği açıklanmaktadır.

Etkinlik

Bir etkinlikte Oluştur'u kullanmak istiyorsanız Oluşturulacak uygun LifecycleOwner ve bileşenleri sağlayan Activity alt sınıfı ComponentActivity kullanmanız gerekir. Ayrıca, kodunuzu etkinlik sınıfınızdaki geçersiz kılma yöntemlerinden ayıran ek API'ler de sağlar. Etkinlik Oluşturma, bu API'leri composable'lara sunar. Böylece, composable'larınızın dışındaki yöntemleri geçersiz kılma veya açık bir Activity örneği alma artık gerekmez. Ayrıca bu API'ler, composable'ın kompozisyondan kaldırılması durumunda yalnızca bir kez başlatılmasını, yeniden derlemede başarılı olmasını ve düzgün şekilde temizlenmesini sağlar.

Etkinlik Sonucu

rememberLauncherForActivityResult() API, composable'ınızdaki bir etkinlikten sonuç almanıza olanak tanır:

@Composable
fun GetContentExample() {
    var imageUri by remember { mutableStateOf<Uri?>(null) }
    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        imageUri = uri
    }
    Column {
        Button(onClick = { launcher.launch("image/*") }) {
            Text(text = "Load Image")
        }
        Image(
            painter = rememberAsyncImagePainter(imageUri),
            contentDescription = "My Image"
        )
    }
}

Bu örnekte basit bir GetContent() sözleşmesi gösterilmektedir. Düğmeye dokunulduğunda istek başlatılır. rememberLauncherForActivityResult() için sondaki lambda, kullanıcı bir resim seçip başlatma etkinliğine döndüğünde çağrılır. Bu işlem, Coil'in rememberImagePainter() işlevini kullanarak seçilen görüntüyü yükler.

Herhangi bir ActivityResultContract alt sınıfı, rememberLauncherForActivityResult() için ilk bağımsız değişken olarak kullanılabilir. Bu, çerçeveden ve diğer yaygın kalıplardan içerik istemek için bu tekniği kullanabileceğiniz anlamına gelir. Ayrıca kendi özel sözleşmelerinizi oluşturabilir ve bunları bu teknikle kullanabilirsiniz.

Çalışma zamanı izinleri isteme

Yukarıda açıklanan aynı Activity Result API ve rememberLauncherForActivityResult(), tek bir izin için RequestPermission sözleşmesini veya birden fazla izin için RequestMultiplePermissions sözleşmesini kullanarak çalışma zamanı izinleri istemek için kullanılabilir.

Eşlikli İzin kitaplığı, izinler için verilen mevcut durumu Compose kullanıcı arayüzünüzün kullanabileceği Duruma eşlemek için bu API'lerin üzerinde bir katman da kullanılabilir.

Sistem geri düğmesini kullanma

composable'ınız, özel geri gezinme sağlamak ve sistem geri düğmesinin varsayılan davranışını composable'ın içinden geçersiz kılmak için bu etkinliğe müdahale etmek üzere bir BackHandler kullanabilir:

var backHandlingEnabled by remember { mutableStateOf(true) }
BackHandler(backHandlingEnabled) {
    // Handle back press
}

İlk bağımsız değişken, BackHandler öğesinin şu anda etkin olup olmadığını kontrol eder. Bu bağımsız değişkeni, bileşeninizin durumuna göre işleyicinizi geçici olarak devre dışı bırakmak için kullanabilirsiniz. Kullanıcı bir sistem geri etkinliğini tetiklerse ve BackHandler etkin durumdaysa sondaki lambda çağrılır.

ViewModel

Architecture Components ViewModel kitaplığını kullanırsanız viewModel() işlevini çağırarak herhangi bir composable'dan bir ViewModel dosyasına erişebilirsiniz.

class MyViewModel : ViewModel() { /*...*/ }

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    // use viewModel here
}

viewModel(), mevcut bir ViewModel değerini döndürür veya belirtilen kapsamda yeni bir kapsam oluşturur. ViewModel, kapsam devam ettiği sürece saklanır. Örneğin, composable bir etkinlikte kullanılırsa etkinlik tamamlanana veya işlem sonlandırılana kadar viewModel() aynı örneği döndürür.

class MyViewModel : ViewModel() { /*...*/ }
// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    // Returns the same instance as long as the activity is alive,
    // just as if you grabbed the instance from an Activity or Fragment
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

@Composable
fun MyScreen2(
    viewModel: MyViewModel = viewModel() // Same instance as in MyScreen
) { /* ... */ }

ViewModelinizde bağımlılıklar varsa viewModel(), parametre olarak isteğe bağlı bir ViewModelProvider.Factory değerini alır.

Compose'da ViewModel özelliği ve örneklerin Navigation Compose kitaplığıyla nasıl kullanıldığı veya etkinlikler ve parçalar hakkında daha fazla bilgi için Birlikte çalışabilirlik belgelerine bakın.

Veri akışları

Compose'da Android'in en popüler akış tabanlı çözümleri için uzantılar bulunur. Bu uzantıların her biri farklı bir yapı tarafından sağlanır:

Bu yapılar dinleyici görevi görür ve değerleri State olarak temsil eder. Yeni bir değer yayınlandığında Compose, bu state.value kullanılan kullanıcı arayüzü bölümlerini yeniden oluşturur. Örneğin, bu kodda exampleLiveData her yeni değer ürettiğinde ShowData yeniden oluşturur.

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    val dataExample = viewModel.exampleLiveData.observeAsState()

    // Because the state is read here,
    // MyScreen recomposes whenever dataExample changes.
    dataExample.value?.let {
        ShowData(dataExample)
    }
}

Compose'da eşzamansız işlemler

Jetpack Compose, composable'larınızın içindeki eş yordamları kullanarak eşzamansız işlemler yürütmenizi sağlar.

Daha fazla bilgi için yan efektler belgelerindeki LaunchedEffect, produceState ve rememberCoroutineScope API'lerine bakın.

Gezinme bileşeni, Jetpack Compose uygulamaları için destek sağlar. Daha fazla bilgi için Compose ile gezinme ve Jetpack Navigation'ı Navigation Compose'a taşıma konularına bakın.

Başlık

Hilt, Android uygulamalarında bağımlılık ekleme için önerilen çözümdür ve Compose ile sorunsuz bir şekilde çalışır.

ViewModel bölümünde bahsedilen viewModel() işlevi, otomatik olarak Hilt'in @HiltViewModel ek açıklamasıyla oluşturduğu ViewModel'i kullanır. Hilt'in ViewModel entegrasyonu hakkında bilgi içeren dokümanlar sağladık.

@HiltViewModel
class MyViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val repository: ExampleRepository
) : ViewModel() { /* ... */ }

// import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
    viewModel: MyViewModel = viewModel()
) { /* ... */ }

İpucu ve Gezinme

Hilt, Navigation Compose kitaplığıyla da entegre olur. Gradle dosyanıza aşağıdaki ek bağımlılıkları ekleyin:

Modern

dependencies {
    implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
}

Kotlin

dependencies {
    implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
}

Gezinmeyi Oluşturma özelliğini kullanırken @HiltViewModel ek açıklamalı ViewModel örneğinizin bir örneğini almak için her zaman hiltViewModel composable işlevini kullanın. Bu özellik, @AndroidEntryPoint ile ek açıklama eklenen parçalar veya etkinlikler için kullanılabilir.

Örneğin, ExampleScreen gezinme grafiğindeki bir hedefse aşağıdaki kod snippet'inde gösterildiği gibi hedefe ayarlanmış bir ExampleViewModel örneği almak için hiltViewModel() çağrısı yapın:

// import androidx.hilt.navigation.compose.hiltViewModel

@Composable
fun MyApp() {
    val navController = rememberNavController()
    val startRoute = "example"
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val viewModel = hiltViewModel<MyViewModel>()
            MyScreen(viewModel)
        }
        /* ... */
    }
}

Bunun yerine gezinme rotaları veya gezinme grafiğine yönelik bir ViewModel örneğini almanız gerekiyorsa hiltViewModel composable işlevini kullanın ve ilgili backStackEntry parametresini parametre olarak iletin:

// import androidx.hilt.navigation.compose.hiltViewModel
// import androidx.navigation.compose.getBackStackEntry

@Composable
fun MyApp() {
    val navController = rememberNavController()
    val startRoute = "example"
    val innerStartRoute = "exampleWithRoute"
    NavHost(navController, startDestination = startRoute) {
        navigation(startDestination = innerStartRoute, route = "Parent") {
            // ...
            composable("exampleWithRoute") { backStackEntry ->
                val parentEntry = remember(backStackEntry) {
                    navController.getBackStackEntry("Parent")
                }
                val parentViewModel = hiltViewModel<ParentViewModel>(parentEntry)
                ExampleWithRouteScreen(parentViewModel)
            }
        }
    }
}

Sayfalama

Çağrı kitaplığı, verileri kademeli olarak yüklemenizi kolaylaştırır ve Compose'da desteklenir. Çağrı sürümü sayfası, projeye ve sürümüne eklenmesi gereken ek paging-compose bağımlılığı hakkında bilgiler içerir.

Aşağıda, Sayfalama kitaplığının Compose API'lerine ilişkin bir örnek verilmiştir:

@Composable
fun MyScreen(flow: Flow<PagingData<String>>) {
    val lazyPagingItems = flow.collectAsLazyPagingItems()
    LazyColumn {
        items(
            lazyPagingItems.itemCount,
            key = lazyPagingItems.itemKey { it }
        ) { index ->
            val item = lazyPagingItems[index]
            Text("Item is $item")
        }
    }
}

Oluşturma'da Sayfalama özelliğini kullanma hakkında daha fazla bilgi için Listeler ve ızgaralar dokümanlarına göz atın.

Haritalar

Uygulamanızda Google Haritalar'ı sağlamak için Haritalar Yazma kitaplığını kullanabilirsiniz. Aşağıda bir kullanım örneği verilmiştir:

@Composable
fun MapsExample() {
    val singapore = LatLng(1.35, 103.87)
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(singapore, 10f)
    }
    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        Marker(
            state = MarkerState(position = singapore),
            title = "Singapore",
            snippet = "Marker in Singapore"
        )
    }
}