Gezinme bileşeni, Jetpack için destek sağlar Uygulamalar oluşturun. composable'lar arasında gezinebilirsiniz. ve Navigasyon bileşeninin altyapısından ve özellikleri.
Kurulum
Compose'u desteklemek için uygulama modülünüzün
build.gradle
dosyası:
Eski
dependencies { def nav_version = "2.7.7" implementation "androidx.navigation:navigation-compose:$nav_version" }
Kotlin
dependencies { val nav_version = "2.7.7" implementation("androidx.navigation:navigation-compose:$nav_version") }
Başlayın
Uygulamada gezinmeyi uygularken bir gezinme ana makinesi uygulayın. grafik ve denetleyicidir. Daha fazla bilgi için Gezinmeye genel bakış bölümünü inceleyin.
NavController oluşturma
Compose'da NavController
oluşturma hakkında bilgi için Oluşturma bölümüne bakın
Gezinme denetleyicisi oluşturma başlıklı makalenin
bölümüne bakın.
NavHost oluşturma
Compose'da NavHost
oluşturma hakkında bilgi için Oluştur bölümüne bakın
Gezinme grafiğinizi tasarlama başlıklı makaleye göz atın.
Bir composable'a git
Bir Oluşturulabilir öğeye gitme hakkında bilgi edinmek için bkz. Bir hedef ekleyin belgelerinden faydalanabilirsiniz.
Bağımsız değişkenlerle gezinme
Gezinme Oluşturma, ayrıca composable arasında bağımsız değişkenlerin aktarılmasını da destekler hedefler. Bunu yapmak için URL'nize bağımsız değişken yer tutucuları derin bir dosyaya bağımsız değişkenler eklemeye benzer bağlantısını gezinme kitaplığı:
NavHost(startDestination = "profile/{userId}") {
...
composable("profile/{userId}") {...}
}
Varsayılan olarak, tüm bağımsız değişkenler dize olarak ayrıştırılır. Şu parametrenin arguments
parametresi:
composable()
, NamedNavArgument
nesnelerinin listesini kabul ediyor. Şunları yapabilirsiniz:
navArgument()
yöntemini kullanarak hızlıca bir NamedNavArgument
oluşturabilir ve
ardından tam type
değerini belirtin:
NavHost(startDestination = "profile/{userId}") {
...
composable(
"profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType })
) {...}
}
NavBackStackEntry
öğesindeki bağımsız değişkenleri ayıklamanız gerekir.
composable()
işlevinin lambda'sında kullanılabilir.
composable("profile/{userId}") { backStackEntry ->
Profile(navController, backStackEntry.arguments?.getString("userId"))
}
Bağımsız değişkeni hedefe iletmek için URL'yi rotaya eklemeniz gerekir
navigate
çağrısı yaptığınızda:
navController.navigate("profile/user1234")
Desteklenen türlerin listesi için Verileri şu öğeler arasında iletme: hedefler.
Navigasyon sırasında karmaşık verileri alma
Gezinirken karmaşık veri nesnelerini geçmemeniz önemle tavsiye edilir. Bunun yerine, benzersiz tanımlayıcı gibi gerekli minimum bilgiyi veya başka türden bir kimlik (ör. gezinme işlemleri gerçekleştirilirken bağımsız değişken olarak):
// Pass only the user ID when navigating to a new destination as argument
navController.navigate("profile/user1234")
Karmaşık nesneler, örneğin
veri katmanından yararlanın. Rotayı izledikten sonra hedefinize vardıktan sonra,
kimlik iletildi. ViewModel
içinde aşağıdakilerden sorumlu bağımsız değişkenleri almak için:
veri katmanına erişmek için ViewModel
SavedStateHandle
öğesini kullanın:
class UserViewModel(
savedStateHandle: SavedStateHandle,
private val userInfoRepository: UserInfoRepository
) : ViewModel() {
private val userId: String = checkNotNull(savedStateHandle["userId"])
// Fetch the relevant user information from the data layer,
// ie. userInfoRepository, based on the passed userId argument
private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(userId)
// …
}
Bu yaklaşım, yapılandırma değişiklikleri ve olası yapılandırma değişiklikleri sırasında söz konusu nesne güncellenirken veya dönüştürüldüğünde gerçekleşen tutarsızlıklar.
Neden karmaşık verileri olduğu gibi iletmekten kaçınmanız gerektiği ve desteklenen bağımsız değişken türlerinin listesini görmek için hedefler.
İsteğe bağlı bağımsız değişkenler ekleyin
Gezinme Oluşturma, isteğe bağlı gezinme bağımsız değişkenlerini de destekler. İsteğe bağlı bağımsız değişkenlerden iki açıdan farklıdır:
- Sorgu parametresi söz dizimi (
"?argName={argName}"
) kullanılarak eklenmelidir - Bunların
defaultValue
grubu veyanullable = true
olması gerekir (varsayılan değer dolaylı olaraknull
değerine ayarlanır)
Bu, isteğe bağlı tüm bağımsız değişkenlerin
Liste olarak composable()
işlevi:
composable(
"profile?userId={userId}",
arguments = listOf(navArgument("userId") { defaultValue = "user1234" })
) { backStackEntry ->
Profile(navController, backStackEntry.arguments?.getString("userId"))
}
Artık hedefe hiçbir bağımsız değişken aktarılmamış olsa bile defaultValue
,
bunun yerine "user1234" kullanılır.
Rotalar aracılığıyla bağımsız değişkenleri ele alma yapısı, composable'lar, Navigasyon'dan tamamen bağımsızdır ve kendilerini test edilebilir.
Derin bağlantılar
Gezinme Oluşturma, oluşturulan örtülü derin bağlantıları,
composable()
işlevi de dahildir. deepLinks
parametresi
NavDeepLink
nesneleri bunlar için
navDeepLink()
yöntemi:
val uri = "https://www.example.com"
composable(
"profile?id={id}",
deepLinks = listOf(navDeepLink { uriPattern = "$uri/{id}" })
) { backStackEntry ->
Profile(navController, backStackEntry.arguments?.getString("id"))
}
Bu derin bağlantılar, belirli bir URL'yi, işlemi veya MIME türünü bir
composable'dan bahsetmek istiyorum. Varsayılan olarak, bu derin bağlantılar harici uygulamalara gösterilmez. Alıcı:
bu derin bağlantıları harici olarak kullanılabilir hale getirmek için
<intent-filter>
öğelerini uygulamanızın manifest.xml
dosyasına ekleyin. Derin bağlantılar
bağlantısı varsa aşağıdakini
Manifestin <activity>
öğesi:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Gezinme derin bağlantı olduğunda, otomatik olarak söz konusu composable'a giden derin bağlantılara başka bir uygulama tarafından tetiklenir.
Aynı derin bağlantılar, aynı zamanda bir PendingIntent
oluşturmak için
bir composable'dan uygun derin bağlantı:
val id = "exampleId"
val context = LocalContext.current
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"https://www.example.com/$id".toUri(),
context,
MyActivity::class.java
)
val deepLinkPendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(deepLinkIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
Daha sonra bu deepLinkPendingIntent
öğesini diğer PendingIntent
gibi kullanabilirsiniz:
Derin bağlantı hedefinde uygulamanızı açın.
İç İçe Navigasyon
İç içe gezinme grafikleri oluşturma hakkında bilgi için bkz. İç içe yerleştirilmiş grafikler.
Alttaki gezinme çubuğuyla entegrasyon
NavController
öğesini, composable hiyerarşinizde daha üst bir düzeyde tanımlayarak
Navigasyon'u, alt gezinme bölümü ve diğer bileşenlere
bir bileşenidir. Bu işlem, ekranın alt kısmındaki simgeleri seçerek gezinmenize olanak tanır.
çubuk.
BottomNavigation
ve BottomNavigationItem
bileşenlerini kullanmak için:
androidx.compose.material
bağımlılığını Android uygulamanıza ekleyin.
Modern
dependencies { implementation "androidx.compose.material:material:1.6.8" } android { buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion = "1.5.15" } kotlinOptions { jvmTarget = "1.8" } }
Kotlin
dependencies { implementation("androidx.compose.material:material:1.6.8") } android { buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.15" } kotlinOptions { jvmTarget = "1.8" } }
Alttaki gezinme çubuğundaki öğeleri gezinme grafiğinizdeki rotalara bağlamak için:
Burada görülen Screen
gibi mühürlü bir sınıf tanımlamanız önerilir.
rotayı ve hedeflerin Dize kaynak kimliğini içerir.
sealed class Screen(val route: String, @StringRes val resourceId: Int) {
object Profile : Screen("profile", R.string.profile)
object FriendsList : Screen("friendslist", R.string.friends_list)
}
Ardından bu öğeleri,
BottomNavigationItem
:
val items = listOf(
Screen.Profile,
Screen.FriendsList,
)
BottomNavigation
composable'ınızda mevcut NavBackStackEntry
öğesini alın
currentBackStackEntryAsState()
işlevi kullanılır. Bu giriş size
geçerli NavDestination
erişimi. Her bir öğenin seçilen durumu
Daha sonra BottomNavigationItem
, öğenin rotası karşılaştırılarak belirlenebilir
varış noktasının ve üst varış noktalarının rotası ile
iç içe yerleştirilmiş gezinme kullanıyorsanız
NavDestination
hiyerarşisi.
Öğenin rotası, onClick
lambda'yı bir çağrıya bağlamak için de kullanılır.
navigate
, böylece öğeye dokunduğunuzda ilgili öğeye gidilir. Şunu kullanarak:
saveState
ve restoreState
flag'leri, bu işaretlerin durumu ve
öğe doğru şekilde kaydedildi ve geri yüklendi
öğeler.
val navController = rememberNavController()
Scaffold(
bottomBar = {
BottomNavigation {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { screen ->
BottomNavigationItem(
icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
label = { Text(stringResource(screen.resourceId)) },
selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
onClick = {
navController.navigate(screen.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
)
}
}
}
) { innerPadding ->
NavHost(navController, startDestination = Screen.Profile.route, Modifier.padding(innerPadding)) {
composable(Screen.Profile.route) { Profile(navController) }
composable(Screen.FriendsList.route) { FriendsList(navController) }
}
}
Burada NavController.currentBackStackEntryAsState()
avantajından yararlanıyorsunuz.
navController
durumunu NavHost
işlevinden kaldırma yöntemini ve
BottomNavigation
bileşeniyle paylaşın. Bu,
BottomNavigation
otomatik olarak en güncel duruma sahip olur.
Yazmada Gezinme'de güvenlik yazın
Bu sayfadaki kod tür için güvenli değil. navigate()
hattını arayabilirsiniz
var olmayan rotalar veya yanlış bağımsız değişkenlerle işlev görür. Ancak,
gezinme kodunuzu çalışma zamanında tür açısından güvenli olacak şekilde yapılandırın. Bu şekilde şunları yapabilirsiniz:
kilitlenmeleri önleyin ve şunlardan emin olun:
- Bir hedef veya gezinme grafiğine giderken sağladığınız bağımsız değişkenler gerekli tüm bağımsız değişkenlerin mevcut olduğundan emin olun.
SavedStateHandle
öğesinden aldığınız bağımsız değişkenler doğru türdedir.
Bu konuda daha fazla bilgi için Kotlin DSL'de ve Navigasyon'da tür güvenliği başlıklı makaleyi inceleyin. Oluştur'u tıklayın.
Birlikte çalışabilirlik
Oluştur ile Gezinme bileşenini kullanmak istiyorsanız iki seçeneğiniz vardır:
- Parçalar için Gezinme bileşeniyle bir gezinme grafiği tanımlayın.
- Oluşturma'da Oluştur'u kullanarak
NavHost
ile bir gezinme grafiği tanımlayın hedefler. Bu yalnızca gezinmedeki tüm ekranlar composable, composable.
Bu nedenle, karma Oluşturma ve Görünüm uygulamaları için öneri Parçaya dayalı Gezinme bileşeni. Parçalar daha sonra Görüntülemeye dayalı Ekranlar, Oluştur ekranları ve hem Görünümler hem de Oluştur özelliklerini kullanan ekranlar. Her biri Parçanın içerikleri Compose'da. Sonraki adım bu ekranları bağlamak oluşturma ve tüm Parçalar'ı kaldırma olanağı sağlar.
Parçalar için Gezinme ile Oluştur'dan gitme
Oluşturma kodu içindeki hedefleri değiştirmek için şunları yapabilecek etkinlikleri kullanıma sunarsınız: hiyerarşideki herhangi bir composable'a geçirilebilir ve tetiklenebilir:
@Composable
fun MyScreen(onNavigate: (Int) -> Unit) {
Button(onClick = { onNavigate(R.id.nav_profile) } { /* ... */ }
}
Parçanızda, Compose ile parça tabanlı arasındaki köprüyü
NavController
öğesini bulup
hedef:
override fun onCreateView( /* ... */ ) {
setContent {
MyScreen(onNavigate = { dest -> findNavController().navigate(dest) })
}
}
Alternatif olarak NavController
öğesini Compose hiyerarşinizde aşağı aktarabilirsiniz.
Ancak basit işlevlerin gösterilmesi çok daha fazla yeniden kullanılabilir ve test edilebilir.
Test
Testi etkinleştirmek için gezinme kodunu composable hedeflerinizden ayırın
NavHost
composable'dan ayrı olarak her composable'ı ayrı ayrı sunuyor.
Bu, navController
öğesini doğrudan
composable olarak ayarlayın ve bunun yerine gezinme geri çağırmalarını parametre olarak iletin. Bu da
composable'ların test gerektirmesi ya da test edebilmeleri için
testlerde navController
örneği.
composable
lambda'nın sağladığı dolaylı yoldan
Gezinme kodunuzu composable'dan ayırın. Bu yöntem iki dilde çalışır:
yol tarifi:
- composable'ınıza yalnızca ayrıştırılan bağımsız değişkenleri iletin
- Gezinmek için composable'ın tetiklemesi gereken lambda'ları iletin,
NavController
ile başlar.
Örneğin, giriş olarak userId
alan veProfile
kullanıcının, arkadaşının profil sayfasına gitmesi için aşağıdaki imzası bulunabilir:
@Composable
fun Profile(
userId: String,
navigateToFriendProfile: (friendUserId: String) -> Unit
) {
…
}
Bu şekilde, Profile
composable, Navigasyon,
Böylece bağımsız olarak test edilebilir. composable
lambda
Navigasyon ile süreç arasındaki boşluğu doldurmak için gereken
API'ler ve composable'ınız:
composable(
"profile?userId={userId}",
arguments = listOf(navArgument("userId") { defaultValue = "user1234" })
) { backStackEntry ->
Profile(backStackEntry.arguments?.getString("userId")) { friendUserId ->
navController.navigate("profile?userId=$friendUserId")
}
}
Uygulamada gezinme şartlarınızı kapsayan testler yazmanız önerilir
NavHost
test edildiğinde, gezinme işlemleri
kendi ekran composable'larınıza kolayca erişebilmenizi sağlar.
NavHost
test ediliyor
NavHost
cihazınızı test etmeye başlamak için aşağıdaki gezinme testini ekleyin
bağımlılık:
dependencies {
// ...
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
// ...
}
NavHost
test kişinizi oluşturabilir ve
navController
örneğinin bir örneğini burada görebilirsiniz. Bunun için gezinme
test yapısı bir TestNavHostController
sağlar. Kullanıcı arayüzü testi,
uygulamanızın başlangıç hedefini doğrular ve NavHost
şöyle görünür:
class NavigationTest {
@get:Rule
val composeTestRule = createComposeRule()
lateinit var navController: TestNavHostController
@Before
fun setupAppNavHost() {
composeTestRule.setContent {
navController = TestNavHostController(LocalContext.current)
navController.navigatorProvider.addNavigator(ComposeNavigator())
AppNavHost(navController = navController)
}
}
// Unit test
@Test
fun appNavHost_verifyStartDestination() {
composeTestRule
.onNodeWithContentDescription("Start Screen")
.assertIsDisplayed()
}
}
Gezinme işlemlerini test etme
Gezinme uygulamanızı çeşitli yollarla test edebilirsiniz: kullanıcı arayüzü öğelerini tıklar ve ardından, görüntülenen hedefi doğrulayarak veya beklenen rotayı mevcut rotayla karşılaştırarak kullanabilirsiniz.
Beton uygulamanızın uygulamasını test etmek istediğinizde, Kullanıcı arayüzleri tercih edilir. Bunu bağımsız composable ile birlikte test etmeyi öğrenmek için işlevlerini gerçekleştirdiğinden emin olmak için Jetpack Compose'da test codelab'i.
Onaylarınızı kontrol etmek için navController
öğesini de kullanabilirsiniz.
mevcut Dize rotasını beklenen rotayla karşılaştırarak
navController
adlı kullanıcının currentBackStackEntry
cihazı:
@Test
fun appNavHost_clickAllProfiles_navigateToProfiles() {
composeTestRule.onNodeWithContentDescription("All Profiles")
.performScrollTo()
.performClick()
val route = navController.currentBackStackEntry?.destination?.route
assertEquals(route, "profiles")
}
Oluşturma testiyle ilgili temel bilgiler hakkında daha fazla yardım için bkz. Compose düzeninizi test etme ve Jetpack Compose'da test etme codelab'e göz atın. Gezinme kodunu ileri düzey test etme hakkında daha fazla bilgi edinmek için Testte Gezinme rehberi.
Daha fazla bilgi
Jetpack Navigasyon hakkında daha fazla bilgi edinmek için bkz. Navigasyon'u kullanmaya başlama bileşenini kullanın veya Jetpack'i Gezinme codelab'i oluşturun.
Uygulamanızın gezinme deneyimini farklı ekranlara uyum sağlayacak şekilde nasıl tasarlayacağınızı öğrenmek için yönleri ve form faktörleri hakkında Duyarlı kullanıcı arayüzleri için gezinme.
E-Tablolar ve Google Haritalar'da daha gelişmiş bir Oluşturma gezinme uygulaması iç içe yerleştirilmiş grafikler ve alt gezinme çubuğu gibi kavramları içeren modülerleştirilmiş uygulama entegrasyonu için GitHub'da Now in Android uygulamasına göz atın.
Örnekler
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Compose'da Materyal Tasarım 2
- Jetpack Gezinme'yi Gezinme Oluşturma'ya taşıma
- Kaldırılacak bölge durumu