Add fragment transition animations to Wallpaper Picker
While this CL does improve the transitions a lot (in my view), there are still a number of issues with the transition animations which I will address in subsequent CLs:
1. The SurfaceViews: For now, the SurfaceViews are set to GONE in the exiting fragment when the transition animation starts. That's done because the transitions do not work well when there are SurfaceViews both in the disappearing and the appearing fragment. I'm still investigating whether it is possible to take a screenshot of the SurfaceView and display that during the transition instead of the SurfaceView itself. Otherwise displaying a placeholder rectangle might be our best option.
2. Shortcuts transition: The asynchronous StateFlow based implementation of the shortcuts feature updates some view state after the transition has started, causing e.g. the horizontal shortcut picker to scroll after the transition has ended. If possible, we should prevent that by postponing the transition.
3. Activity transitions: Clicking the preview on the StartScreen starts an activity transition which looks very different from all other transitions. There are multiple other activity transitions in the whole app as well. They should be changed to match the fragment transitions.
4. Shared elements: I see some potential improvements to the transitions by adding shared elements. (E.g. the top navigation bar). I will reach out to the design team to see what they think.
Bug: 278929581
Flag: WALLPAPER_PICKER_PAGE_TRANSITIONS
Test: Manual, i.e. analysing screen recordings of fragment transition animations
Change-Id: Ie1151edc0f53c16e5597a24715f8b9dd431d1f83
diff --git a/res/layout/fragment_clock_settings.xml b/res/layout/fragment_clock_settings.xml
index bb4a0c2..5736265 100644
--- a/res/layout/fragment_clock_settings.xml
+++ b/res/layout/fragment_clock_settings.xml
@@ -19,7 +19,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:clipChildren="false">
+ android:clipChildren="false"
+ android:transitionGroup="true">
<FrameLayout
android:id="@+id/section_header_container"
diff --git a/res/layout/fragment_lock_screen_quick_affordances.xml b/res/layout/fragment_lock_screen_quick_affordances.xml
index 36d1697..ee259f1 100644
--- a/res/layout/fragment_lock_screen_quick_affordances.xml
+++ b/res/layout/fragment_lock_screen_quick_affordances.xml
@@ -19,7 +19,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:clipChildren="false">
+ android:clipChildren="false"
+ android:transitionGroup="true">
<FrameLayout
android:id="@+id/section_header_container"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index c70b596..b2c22b2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -48,6 +48,7 @@
<item name="colorSurface">@color/design_default_color_surface</item>
<item name="colorOnSurface">@color/design_default_color_on_surface</item>
<item name="android:textAllCaps">false</item>
+ <item name="motionDurationLong1">500</item>
</style>
<!-- Snackbar margin -->
diff --git a/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt b/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt
index 6ab561f..b04c194 100644
--- a/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt
+++ b/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt
@@ -21,7 +21,10 @@
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
+import androidx.transition.Transition
+import androidx.transition.doOnStart
import com.android.customization.model.grid.ui.binder.GridScreenBinder
import com.android.customization.model.grid.ui.viewmodel.GridScreenViewModel
import com.android.customization.module.ThemePickerInjector
@@ -85,6 +88,10 @@
}
)
+ (returnTransition as? Transition)?.doOnStart {
+ view.requireViewById<View>(R.id.preview).isVisible = false
+ }
+
return view
}
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
index f4684d8..0b02ed9 100644
--- a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
+++ b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
@@ -20,8 +20,11 @@
import android.view.View
import android.view.ViewGroup
import androidx.cardview.widget.CardView
+import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.get
+import androidx.transition.Transition
+import androidx.transition.doOnStart
import com.android.customization.module.ThemePickerInjector
import com.android.customization.picker.clock.ui.binder.ClockSettingsBinder
import com.android.systemui.shared.clocks.shared.model.ClockPreviewConstants
@@ -130,6 +133,8 @@
viewLifecycleOwner,
)
+ (returnTransition as? Transition)?.doOnStart { lockScreenView.isVisible = false }
+
return view
}
diff --git a/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt b/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt
index 78bfa43..a70b509 100644
--- a/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt
+++ b/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt
@@ -22,9 +22,12 @@
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.cardview.widget.CardView
+import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.get
import androidx.lifecycle.lifecycleScope
+import androidx.transition.Transition
+import androidx.transition.doOnStart
import com.android.customization.model.mode.DarkModeSectionController
import com.android.customization.module.ThemePickerInjector
import com.android.customization.picker.color.ui.binder.ColorPickerBinder
@@ -197,6 +200,12 @@
.createView(requireContext())
darkModeSectionView.background = null
darkModeToggleContainerView.addView(darkModeSectionView)
+
+ (returnTransition as? Transition)?.doOnStart {
+ lockScreenView.isVisible = false
+ homeScreenView.isVisible = false
+ }
+
return view
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
index d5f0d33..4cedc4f 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
@@ -21,8 +21,11 @@
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.get
+import androidx.transition.Transition
+import androidx.transition.doOnStart
import com.android.customization.module.ThemePickerInjector
import com.android.customization.picker.quickaffordance.ui.binder.KeyguardQuickAffordancePickerBinder
import com.android.customization.picker.quickaffordance.ui.binder.KeyguardQuickAffordancePreviewBinder
@@ -77,6 +80,10 @@
viewModel = viewModel,
lifecycleOwner = this,
)
+ (returnTransition as? Transition)?.doOnStart {
+ // Hide preview during exit transition animation
+ view?.findViewById<View>(R.id.preview)?.isVisible = false
+ }
return view
}