I am using a BottomNavigation
with 4 composables. All of them have a LazyColumn
with each item in the LazyColumn
having an image populated from the network using Coil for Jetpack Compose. Similar to Twitter/YouTube.
When I navigate between these items, the composables get destroyed and recompose only when navigated back to them. Even the coil images are cleared and re-fetched (from memory or local storage) when navigated between these composables. This is of course the expected behavior.
The problem is that this is causing the navigation between them to be too slow. Coil images take about 400ms to 700ms to load the image for every navigation. Apps like YouTube/LinkedIn are literally instant in their BottomBar
navigations.
When I was using XML for this, I would make the fragments(used as bottom nav items ) with an appear/disappear logic to avoid this time delay while navigating between them.
How do I achieve the same with Compose ?
I am using the following versions:
//compose navigation
implementation "androidx.navigation:navigation-compose:2.4.0-beta01"
implementation "com.google.accompanist:accompanist-navigation-animation:0.21.0-beta"
Well I had the same problem using emulator or phone
both work well with small simplistic composables. And when I create more complex Composable and try animating the navigation, using the accompanist animation library it gets very laggy.
But then I tried building the release APK file, since it is usually optimized and way faster, and that will significantly speed up your app. Here is link on how you can generate signed APK then install it on your phone or emulator and see if that fixes your problem!
You could also check if you accidentally disabled the hardware acceleration from the manifest. Make sure you set android:hardwareAccelerated="true"
in you activity tag.
In case that does not help either, then you have to implement your own animation and use Shared ViewModel, for communication and triggering the transition from one Composable to another. The idea is that you can use modifier offset
property to show/hide the Composable by placing it outside the screen.
First set your ViewModel, and add mutable state variable, that will trigger the transition from Home to Settings and vice versa.
This is not the best practice, since there is no way to directly pass data from one composable to another as you would normally do with the normal navigation. But you can still share data using the Shared ViewModel. Using this method it will not recompose your Composable, and thus be really fast. So far I have no problem with any out of memory exceptions even on some very old/slow devices with 2GB RAM.
class SharedViewModel : ViewModel() {
// changing this mutable state will trigger the transition animation
private val _switchHomeToSetting = mutableStateOf(true)
val switchHomeToSetting: State<Boolean> = _switchHomeToSetting
fun switchHomeToSettings() {
_switchHomeToSetting.value = !_switchHomeToSetting.value
}
}
Now create your two Composable functions Home and Settings respectively
@Composable
fun HomeScreen(viewModel: SharedViewModel) {
// draw your subcomponents
}
@Composable
fun SettingsScreen(viewModel: SharedViewModel) {
// draw your subcomponents
}
And finally initialize the animation in you main activity
class MainActivity : ComponentActivity() {
val viewModel by viewModels<CityWeatherViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// set your offset animation
val density = LocalDensity.current
val width = with(density) { (1.adw).toPx() }
val animatedOffsetX: Float by animateFloatAsState(
targetValue = if (!viewModel.switchHomeToSetting.value) 0f else width,
animationSpec = tween(1200)
)
// Home screen
Box(
modifier = Modifier
.fillMaxSize()
.offset { IntOffset((-width + animatedOffsetX).toInt(), 0) }
) {
HomeScreen(viewModel = viewModel)
}
// Settings screen
Box(
modifier = Modifier
.fillMaxSize()
.offset { IntOffset(animatedOffsetX.toInt(), 0) }
) {
SettingsScreen(viewModel = viewModel)
}
}
}
}
Here is the result using the Composable Navigation, together with the Accompanist Animation. As you can see it is very laggy indeed
And now here is the result using our custom animation, where it is very smooth since no Composable is recomposed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With