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

Compose'da favori kitaplıklarınızı kullanabilirsiniz. Bu bölümde, en faydalı kitaplıklardan birkaçını nasıl dahil edeceğiniz açıklanmaktadır.

Etkinlik

Bir etkinlikte Compose'u kullanmak için ComponentActivity kullanmanız gerekir. Bu, Compose'a uygun LifecycleOwner ve bileşenleri sağlayan bir Activity alt sınıfıdır. Ayrıca, kodunuzu etkinlik sınıfınızdaki geçersiz kılma yöntemlerinden ayıran ek API'ler de sağlar. Activity Compose, bu API'leri composable'lara gösterir. Böylece composable'larınızın dışındaki yöntemleri geçersiz kılmanız veya açık bir Activity örneği almanız gerekmez. Ayrıca bu API'ler, yalnızca bir kez başlatılmalarını, yeniden oluşturma işleminden etkilenmemelerini ve composable, oluşturma işleminden kaldırılırsa düzgün bir şekilde temizlenmelerini sağlar.

Etkinlik Sonucu

rememberLauncherForActivityResult() API'si, composable'ınızda 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, Coil'in rememberImagePainter() işlevini kullanarak seçilen resmi yükler.

ActivityResultContract sınıfının herhangi bir alt sınıfı, rememberLauncherForActivityResult() için ilk bağımsız değişken olarak kullanılabilir. Bu teknikle çerçeveden içerik isteyebilir ve diğer yaygın kalıplarda kullanabilirsiniz. Ayrıca kendi özel sözleşmelerinizi oluşturabilir ve bu teknikle kullanabilirsiniz.

Çalışma zamanında istenen izinleri isteme

Yukarıda açıklanan 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ında istenen izinleri istemek amacıyla kullanılabilir.

Accompanist Permissions kitaplığı, izinler için mevcut izin durumunu Compose kullanıcı arayüzünüzün kullanabileceği duruma eşlemek amacıyla bu API'lerin üzerinde bir katman olarak da kullanılabilir.

Sistem geri düğmesini kullanma

Özel geri gezinme sağlamak ve sistem geri düğmesinin varsayılan davranışını composable'ınızdan geçersiz kılmak için composable'ınız, bu etkinliği yakalamak üzere bir BackHandler kullanabilir:

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

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

ViewModel

Architecture Components ViewModel kitaplığını kullanıyorsanız viewModel() işlevini çağırarak herhangi bir composable'dan ViewModel'a erişebilirsiniz. Gradle dosyanıza aşağıdaki bağımlılığı ekleyin:

Modern

dependencies {
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0'
}

Kotlin

dependencies {
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0")
}

Ardından kodunuzda viewModel() işlevini kullanabilirsiniz.

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

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

viewModel(), mevcut bir ViewModel döndürür veya yeni bir tane oluşturur. Varsayılan olarak, döndürülen ViewModel, kapsayan etkinliğe, parçaya veya gezinme hedefine göre kapsamlandırılır ve kapsam etkin olduğu sürece saklanır.

Örneğin, composable bir etkinlikte kullanılıyorsa viewModel(), etkinlik tamamlanana veya işlem sonlandırılana kadar 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
) { /* ... */ }

Kullanım talimatları

ViewModel örneklerine genellikle ekran düzeyindeki composable'larda, yani bir etkinlik, fragment veya gezinme grafiğinin hedefinden çağrılan kök composable'a yakın bir yerde erişirsiniz. Bunun nedeni, ViewModels öğelerinin varsayılan olarak bu ekran düzeyindeki nesnelerle kapsamlandırılmasıdır. ViewModel'ın yaşam döngüsü ve kapsamı hakkında daha fazla bilgi edinin.

ViewModel örneklerini diğer composable'lara aktarmaktan kaçının. Bu, composable'ların test edilmesini zorlaştırabilir ve önizlemeleri bozabilir. Bunun yerine, yalnızca ihtiyaç duydukları verileri ve işlevleri parametre olarak iletin.

Ekran altı düzeyindeki composable'ların durumunu yönetmek için ViewModel örneklerini kullanabilirsiniz ancak ViewModel'nin yaşam döngüsünü ve kapsamını göz önünde bulundurun. Bağımsız bir composable kullanıyorsanız üst composable'lardan bağımlılıkları iletmek zorunda kalmamak için Hilt kitaplığı kullanarak ViewModel yerleştirebilirsiniz.

ViewModel öğenizin bağımlılıkları varsa viewModel(), parametre olarak isteğe bağlı bir ViewModelProvider.Factory alır.

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

Veri akışları

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

Bu yapılar dinleyici olarak kaydedilir ve değerleri State olarak temsil eder. Yeni bir değer yayınlandığında Compose, kullanıcı arayüzünün bu state.value değerinin kullanıldığı bölümlerini yeniden oluşturur. Örneğin, bu kodda ShowData, exampleLiveData her yeni değer yayınladığında yeniden oluşturulur.

// 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, eş yordamları kullanarak composable'larınızdan eşzamansız işlemler yürütmenize olanak tanır.

Daha fazla bilgi için yan etkilerle ilgili dokümanlardaki 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 başlıklı makaleleri inceleyin.

Hilt kitaplığı

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

ViewModel bölümünde bahsedilen viewModel() işlevi, Hilt'in @HiltViewModel ek açıklamasıyla oluşturduğu ViewModel'i otomatik olarak kullanır. Hilt'in ViewModel entegrasyonu hakkında bilgi içeren belgeler 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()
) { /* ... */ }

Hilt 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.4.0'
}

Kotlin

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

Navigation Compose'u kullanırken @HiltViewModel ek açıklamalı ViewModel örneği elde etmek için her zaman hiltViewModel composable işlevini kullanın. Bu, @AndroidEntryPoint ile ek açıklama eklenmiş parçalar veya etkinliklerle çalışır.

Örneğin, ExampleScreen bir gezinme grafiğinde hedefse aşağıdaki kod snippet'inde gösterildiği gibi hedefe göre kapsamı belirlenmiş bir ExampleViewModel örneği almak için hiltViewModel() yöntemini çağırı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ği kapsamındaki bir ViewModel örneğini almanız gerekiyorsa hiltViewModel composable işlevini kullanın ve ilgili backStackEntry değerini 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)
            }
        }
    }
}

Sayfalandırma

Paging kitaplığı, verileri kademeli olarak yüklemenizi kolaylaştırır ve Compose'da desteklenir. Paging sürüm sayfasında, projeye eklenmesi gereken ek paging-compose bağımlılığı ve sürümü hakkında bilgi yer alır.

Paging kitaplığının Compose API'lerine bir örnek:

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

Compose'da Paging kullanımı hakkında daha fazla bilgi için Listeler ve ızgaralar belgelerine göz atın.

Haritalar

Uygulamanızda Google Haritalar'ı kullanmak için Haritalar Compose kitaplığından yararlanabilirsiniz. Kullanım örneğini aşağıda bulabilirsiniz:

@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 = remember { MarkerState(position = singapore) },
            title = "Singapore",
            snippet = "Marker in Singapore"
        )
    }
}