Fixed
Status Update
Comments
cl...@google.com <cl...@google.com>
ap...@google.com <ap...@google.com> #2
Project: platform/frameworks/support
Branch: androidx-master-dev
commit e005db789e4c6b6c75fb8ca03a0c4e326868fb91
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed Sep 02 14:20:41 2020
Move nav_default animation out of animation sets
All of the nav_default animations are simple fades and do not need to be
inside of a animation set. Moving them out also ensures that if they are
placed in an additional set (i.e. like the new fragment state manager
does to listen for when the animation finishes) they will not flash.
Bug: 167430145
Test: Tested in sample app
Change-Id: I071e922a52301863ba2461ff05b60bb64566430c
M navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml
https://android-review.googlesource.com/1418719
Branch: androidx-master-dev
commit e005db789e4c6b6c75fb8ca03a0c4e326868fb91
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed Sep 02 14:20:41 2020
Move nav_default animation out of animation sets
All of the nav_default animations are simple fades and do not need to be
inside of a animation set. Moving them out also ensures that if they are
placed in an additional set (i.e. like the new fragment state manager
does to listen for when the animation finishes) they will not flash.
Bug: 167430145
Test: Tested in sample app
Change-Id: I071e922a52301863ba2461ff05b60bb64566430c
M navigation/navigation-ui/src/main/res/anim/nav_default_enter_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_exit_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_pop_enter_anim.xml
M navigation/navigation-ui/src/main/res/anim/nav_default_pop_exit_anim.xml
cl...@google.com <cl...@google.com> #3
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 1e9ed84322fddd9228df1f96bc8cb76748e0a4fe
Author: Jeremy Woods <jbwoods@google.com>
Date: Fri Sep 11 15:58:27 2020
Add nav default animator resources
Animators are recommeneded over Animations for doing effects in fragment
and Navigation. We need to make default animator resources for
Navigation.
Test: Tested in sample apps
Bug: 167430145
Change-Id: I904d78268d8b8574c799ae1b0f5887e518fdb5f6
M navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.java
M navigation/navigation-ui/src/main/res-public/values/public_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_enter_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_exit_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_pop_enter_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_pop_exit_anim.xml
https://android-review.googlesource.com/1424849
Branch: androidx-master-dev
commit 1e9ed84322fddd9228df1f96bc8cb76748e0a4fe
Author: Jeremy Woods <jbwoods@google.com>
Date: Fri Sep 11 15:58:27 2020
Add nav default animator resources
Animators are recommeneded over Animations for doing effects in fragment
and Navigation. We need to make default animator resources for
Navigation.
Test: Tested in sample apps
Bug: 167430145
Change-Id: I904d78268d8b8574c799ae1b0f5887e518fdb5f6
M navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.java
M navigation/navigation-ui/src/main/res-public/values/public_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_enter_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_exit_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_pop_enter_anim.xml
A navigation/navigation-ui/src/main/res/animator/nav_default_pop_exit_anim.xml
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 9c1b0badcfb5fa6d11c1ec64c224c6be08b9211d
Author: Jeremy Woods <jbwoods@google.com>
Date: Fri Sep 11 16:18:20 2020
Fix resource tracking for navigation UI
We need to move the public navigation UI resources from the legacy
res-public director to the supported values/public.xml file to ensure
that the resources are being properly tracked.
This change also marks the default nav animations are deprecated in
favor of animators.
Test: Tested in sample apps
Bug: 167430145
Change-Id: Ife64d85b280d6ed1161efe503885f807066b710c
M navigation/navigation-ui/api/res-current.txt
D navigation/navigation-ui/src/main/res-public/values/public_anim.xml
A navigation/navigation-ui/src/main/res/values/public.xml
https://android-review.googlesource.com/1419330
Branch: androidx-master-dev
commit 9c1b0badcfb5fa6d11c1ec64c224c6be08b9211d
Author: Jeremy Woods <jbwoods@google.com>
Date: Fri Sep 11 16:18:20 2020
Fix resource tracking for navigation UI
We need to move the public navigation UI resources from the legacy
res-public director to the supported values/public.xml file to ensure
that the resources are being properly tracked.
This change also marks the default nav animations are deprecated in
favor of animators.
Test: Tested in sample apps
Bug: 167430145
Change-Id: Ife64d85b280d6ed1161efe503885f807066b710c
M navigation/navigation-ui/api/res-current.txt
D navigation/navigation-ui/src/main/res-public/values/public_anim.xml
A navigation/navigation-ui/src/main/res/values/public.xml
Description
Devices/Android versions reproduced on: API 33
Animation is broken when navigating between two NavGraphs while using the NavOption popUpTo(0) { inclusive = true }. Not a problem when val zIndex = composeNavigator.backStack.value.size.toFloat() as NavHost returns increasing indices for subsequent screens.
However, when popping all back stack entries, the index for the next screen is reset to 1.0 at some point resulting in the broken animation. Attached video of broken animation.
Repro code
```
package com.example.myapplication
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.navigation
import com.example.myapplication.ui.theme.MyApplicationTheme
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import org.w3c.dom.Text
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface {
MyNavHost()
}
}
}
}
}
val SUBGRAPH1 = "Subgraph1"
val FIRSTVIEW1 = "FirstView1"
val SECONDVIEW1 = "SecondView1"
val SUBGRAPH2 = "Subgraph2"
val FIRSTVIEW2 = "FirstView2"
val SECONDVIEW2 = "SecondView2"
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun MyNavHost() {
val navController = rememberAnimatedNavController()
val durationMillis = 1500
val offsetAnimationSpec: FiniteAnimationSpec<IntOffset> = remember { tween(durationMillis) }
val floatAnimationSpec: FiniteAnimationSpec<Float> = remember { tween(durationMillis) }
// the start destination is always the welcome screen so we can popToRoot at any time
// only when a user is set, we navigate to the map directly without animation
AnimatedNavHost(
navController = navController,
startDestination = SUBGRAPH1,
enterTransition = {
slideInHorizontally(
initialOffsetX = { it / 2 },
animationSpec = offsetAnimationSpec
) + fadeIn(animationSpec = floatAnimationSpec)
},
exitTransition = {
slideOutHorizontally(
targetOffsetX = { -it / 2 },
animationSpec = offsetAnimationSpec
)
},
popEnterTransition = {
slideInHorizontally(
initialOffsetX = { -it / 2 },
animationSpec = offsetAnimationSpec
)
},
popExitTransition = {
slideOutHorizontally(
targetOffsetX = { it / 2 },
animationSpec = offsetAnimationSpec
) + fadeOut(animationSpec = floatAnimationSpec)
},
modifier = Modifier.fillMaxSize()
) {
navGraph1(navController)
navGraph2(navController)
}
}
@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.navGraph1(
navController: NavController
) {
navigation(
startDestination = FIRSTVIEW1,
route = SUBGRAPH1
) {
composable(FIRSTVIEW1) {
PlaceholderComposable(
text = FIRSTVIEW1,
color = Color.Green,
onNext = { navController.navigate(SECONDVIEW1) }
)
}
composable(SECONDVIEW1) {
PlaceholderComposable(
text = SECONDVIEW1,
color = Color.Red,
onNext = { navController.navigate(SUBGRAPH2) },
onPrevious = { navController.navigateUp() }
)
}
}
}
@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.navGraph2(
navController: NavController
) {
navigation(
startDestination = FIRSTVIEW2,
route = SUBGRAPH2
) {
composable(FIRSTVIEW2) {
PlaceholderComposable(
text = FIRSTVIEW2,
color = Color.Yellow,
onNext = {
navController.navigate(SECONDVIEW2) {
popUpTo(0) { inclusive = true }
}
},
onPrevious = { navController.navigateUp() }
)
}
composable(SECONDVIEW2) {
PlaceholderComposable(
text = SECONDVIEW2,
color = Color.Blue,
onNext = {
navController.navigate(SUBGRAPH1) {
popUpTo(0) { inclusive = true }
}
}
)
}
}
}
@Composable
fun PlaceholderComposable(
text: String,
color: Color,
onNext: (() -> Unit)? = null,
onPrevious: (() -> Unit)? = null
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(color),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = text)
Row {
onPrevious?.let { callback ->
Button(
onClick = { callback() },
modifier = Modifier.padding(8.dp)
) {
Text(text = "Previous")
}
}
onNext?.let { callback ->
Button(
onClick = { callback() },
modifier = Modifier.padding(8.dp)
) {
Text(text = "Next")
}
}
}
}
}
```
Steps to repro
1. click "next"
2. click "previous"
3. click "next"
4. click "next"
5. click "next"