शर्तों के हिसाब से ट्रांज़िशन करने का आसान तरीका
इस रेसिपी में, transitionSpec और popTransitionSpec का इस्तेमाल करके, Navigation 3 में रूट के हिसाब से स्क्रीन ट्रांज़िशन बनाने का तरीका बताया गया है. स्लाइड की दिशाएं (दाईं, बाईं, नीचे, ऊपर), initialState और targetState नेविगेशन कुंजियों के जोड़े के आधार पर चुनी जाती हैं.
यह कैसे काम करता है
- रास्ते की परिभाषाएं: नेविगेशन डेस्टिनेशन (
Step1,Step2,Step3,Step4) को सील की गई क्लास के क्रम के हिसाब से तय किया जाता है. इसमेंNavKeyको लागू किया जाता है और इसे@Serializableके तौर पर मार्क किया जाता है. - शर्तों के साथ आगे बढ़ने वाले ट्रांज़िशन (
transitionSpec): स्लाइड ऐनिमेशन की दिशा तय करने के लिए,(initialKey to targetKey)के जोड़े मैच करता है:Step1$\rightarrow$Step2: बाईं ओर स्वाइप करता हैStep2$\rightarrow$Step3: ऊपर की ओर स्वाइप करेंStep3$\rightarrow$Step4: दाईं ओर स्वाइप करेंStep4$\rightarrow$Step1: नीचे की ओर स्लाइड करता है (फ़्लो फिर से शुरू होता है)
- शर्तों के साथ पॉप ट्रांज़िशन (
popTransitionSpec): यह वापस नेविगेट करते समय या बैकस्टैक को मिटाते समय, स्लाइड की दिशाओं को उलट देता है. - बैकस्टैक कंट्रोल: इसमें, टॉप-स्लाइड ट्रांज़िशन को आसानी से लागू करते समय, आखिरी चरण (
backStack.clear()औरbackStack.add(Step1)) पर नेविगेशन स्टैक को हटाने का तरीका दिखाया गया है.
package com.example.nav3recipes.conditionaltransitions import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.animation.ContentTransform import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutVertically import androidx.compose.animation.togetherWith import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.ElevatedButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.ui.NavDisplay import com.example.nav3recipes.content.ContentGreen import com.example.nav3recipes.content.ContentOrange import com.example.nav3recipes.content.ContentPurple import com.example.nav3recipes.content.ContentRed import com.example.nav3recipes.sharedviewmodel.toContentKey import com.example.nav3recipes.ui.setEdgeToEdgeConfig import dagger.hilt.android.AndroidEntryPoint import kotlinx.serialization.Serializable @Serializable sealed class Step(val firstButtonTitle: String, val secondButtonTitle: String) : NavKey @Serializable data object Step1 : Step("Home", "Swipe left") @Serializable data object Step2 : Step("Swipe right", "Swipe up") @Serializable data object Step3 : Step("Swipe down", "Swipe right") @Serializable data object Step4 : Step("Swipe left", "Swipe down") @AndroidEntryPoint class ConditionalTransitionsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setEdgeToEdgeConfig() setContent { Scaffold { paddingValues -> val backStack = rememberNavBackStack(Step1) NavDisplay( backStack = backStack, modifier = Modifier.padding(paddingValues), onBack = backStack::removeLastOrNull, entryProvider = entryProvider { entry<Step1> { ContentGreen(title = "Screen 1") { StepContent( step = it, onNext = { backStack += Step2 }, onBack = ::finish, // closing the activity ) } } entry<Step2> { ContentRed(title = "Screen 2") { StepContent( step = it, onNext = { backStack += Step3 }, onBack = backStack::removeLastOrNull, ) } } entry<Step3> { ContentOrange(title = "Screen 3") { StepContent( step = it, onNext = { backStack += Step4 }, onBack = backStack::removeLastOrNull, ) } } entry<Step4> { ContentPurple(title = "Screen 4") { StepContent( step = it, onNext = { backStack.clear() backStack.add(Step1) }, onBack = backStack::removeLastOrNull, ) } } }, transitionSpec = { val initialKey = initialState.entries.lastOrNull()?.contentKey val targetKey = targetState.entries.lastOrNull()?.contentKey when (initialKey to targetKey) { Step1.toContentKey() to Step2.toContentKey() -> swipeLeft() Step2.toContentKey() to Step3.toContentKey() -> swipeUp() Step3.toContentKey() to Step4.toContentKey() -> swipeRight() Step4.toContentKey() to Step1.toContentKey() -> swipeDown() else -> swipeRight() } }, popTransitionSpec = { val initialKey = initialState.entries.lastOrNull()?.contentKey val targetKey = targetState.entries.lastOrNull()?.contentKey when (initialKey to targetKey) { Step4.toContentKey() to Step1.toContentKey() -> swipeDown() // via backstack clearing Step2.toContentKey() to Step1.toContentKey() -> swipeRight() Step3.toContentKey() to Step2.toContentKey() -> swipeDown() Step4.toContentKey() to Step3.toContentKey() -> swipeLeft() else -> swipeLeft() } }, ) } } } } @Composable fun StepContent(step: Step, onNext: () -> Unit, onBack: () -> Unit) { Column( verticalArrangement = Arrangement.SpaceEvenly, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxSize() ) { Row(horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.fillMaxWidth()) { ElevatedButton(onBack) { Text(text = step.firstButtonTitle) } ElevatedButton(onNext) { Text(text = step.secondButtonTitle) } } } } private fun swipeLeft(): ContentTransform = slideInHorizontally(initialOffsetX = { it }) togetherWith slideOutHorizontally(targetOffsetX = { -it }) private fun swipeUp(): ContentTransform = slideInVertically(initialOffsetY = { it }) togetherWith slideOutVertically(targetOffsetY = { -it }) private fun swipeRight(): ContentTransform = slideInHorizontally(initialOffsetX = { -it }) togetherWith slideOutHorizontally(targetOffsetX = { it }) private fun swipeDown(): ContentTransform = slideInVertically(initialOffsetY = { -it }) togetherWith slideOutVertically(targetOffsetY = { it })