From de081e401d89c71bf82c7513a66a479219b158d1 Mon Sep 17 00:00:00 2001 From: Sherry Zhou Date: Tue, 14 Mar 2023 23:34:52 +0000 Subject: Add animations during swiping picker carousel Test: atest SimpleClockScreenshotTest Bug: 271159401 Change-Id: Id52992db917c42852d63af899515e0ae15ed3205 --- .../picker/clock/ui/view/ClockCarouselView.kt | 76 ++++++++++++++++++++-- .../picker/clock/ui/view/ClockViewFactory.kt | 20 ++++-- 2 files changed, 82 insertions(+), 14 deletions(-) (limited to 'src/com/android/customization/picker/clock/ui/view') diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt index 90d7c42d..3eae7aab 100644 --- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt +++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt @@ -22,7 +22,9 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import androidx.constraintlayout.helper.widget.Carousel +import androidx.constraintlayout.motion.widget.MotionLayout import androidx.core.view.get +import com.android.systemui.plugins.ClockController import com.android.wallpaper.R class ClockCarouselView( @@ -35,21 +37,66 @@ class ClockCarouselView( ) { private val carousel: Carousel + private val motionLayout: MotionLayout private lateinit var adapter: ClockCarouselAdapter + private lateinit var scalingUpClock: ClockController + private lateinit var scalingDownClock: ClockController init { - val view = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this) - carousel = view.requireViewById(R.id.carousel) + val clockCarousel = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this) + carousel = clockCarousel.requireViewById(R.id.carousel) + motionLayout = clockCarousel.requireViewById(R.id.motion_container) } fun setUpClockCarouselView( clockIds: List, - onGetClockPreview: (clockId: String) -> View, + onGetClockController: (clockId: String) -> ClockController, onClockSelected: (clockId: String) -> Unit, + getPreviewRatio: () -> Float, ) { - adapter = ClockCarouselAdapter(clockIds, onGetClockPreview, onClockSelected) + adapter = + ClockCarouselAdapter(clockIds, onGetClockController, onClockSelected, getPreviewRatio) carousel.setAdapter(adapter) carousel.refresh() + motionLayout.setTransitionListener( + object : MotionLayout.TransitionListener { + override fun onTransitionStarted( + motionLayout: MotionLayout?, + startId: Int, + endId: Int + ) { + val scalingDownClockId = adapter.clockIds[carousel.currentIndex] + val scalingUpIdx = + if (endId == R.id.next) (carousel.currentIndex + 1) % adapter.count() + else (carousel.currentIndex - 1 + adapter.count()) % adapter.count() + val scalingUpClockId = adapter.clockIds[scalingUpIdx] + scalingDownClock = adapter.onGetClockController(scalingDownClockId) + scalingUpClock = adapter.onGetClockController(scalingUpClockId) + } + + override fun onTransitionChange( + motionLayout: MotionLayout?, + startId: Int, + endId: Int, + progress: Float + ) { + scalingDownClock.animations.onPickerCarouselSwiping( + 1 - progress, + getPreviewRatio() + ) + scalingUpClock.animations.onPickerCarouselSwiping(progress, getPreviewRatio()) + } + + override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {} + + override fun onTransitionTrigger( + motionLayout: MotionLayout?, + triggerId: Int, + positive: Boolean, + progress: Float + ) {} + } + ) } fun setSelectedClockIndex( @@ -60,8 +107,9 @@ class ClockCarouselView( class ClockCarouselAdapter( val clockIds: List, - val onGetClockPreview: (clockId: String) -> View, - val onClockSelected: (clockId: String) -> Unit, + val onGetClockController: (clockId: String) -> ClockController, + private val onClockSelected: (clockId: String) -> Unit, + val getPreviewRatio: () -> Float, ) : Carousel.Adapter { override fun count(): Int { @@ -72,15 +120,29 @@ class ClockCarouselView( val viewRoot = view as ViewGroup val clockHostView = viewRoot[0] as ViewGroup clockHostView.removeAllViews() - val clockView = onGetClockPreview(clockIds[index]) + val clockView = onGetClockController(clockIds[index]).largeClock.view // The clock view might still be attached to an existing parent. Detach before adding to // another parent. (clockView.parent as? ViewGroup)?.removeView(clockView) clockHostView.addView(clockView) + // initialize scaling state for all clocks + if (view.id != MIDDLE_VIEW_IN_START_STATE) { + onGetClockController(clockIds[index]) + .animations + .onPickerCarouselSwiping(0F, getPreviewRatio()) + } else { + onGetClockController(clockIds[index]) + .animations + .onPickerCarouselSwiping(1F, getPreviewRatio()) + } } override fun onNewItem(index: Int) { onClockSelected.invoke(clockIds[index]) } } + + companion object { + const val MIDDLE_VIEW_IN_START_STATE = R.id.item_view_2 + } } diff --git a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt index 3222c877..67c70027 100644 --- a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt +++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt @@ -33,9 +33,20 @@ class ClockViewFactory( ) { private val timeTickListeners: ConcurrentHashMap = ConcurrentHashMap() private val clockControllers: HashMap = HashMap() + private var ticker: TimeTicker? = null + fun getRatio(): Float { + val screenSizeCalculator = ScreenSizeCalculator.getInstance() + val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay) + return activity.resources.getDimensionPixelSize(R.dimen.screen_preview_height).toFloat() / + screenSize.y.toFloat() + } + + fun getController(clockId: String): ClockController { + return clockControllers[clockId] ?: initClockController(clockId) + } fun getView(clockId: String): View { - return (clockControllers[clockId] ?: initClockController(clockId)).largeClock.view + return getController(clockId).largeClock.view } fun updateColorForAllClocks(@ColorInt seedColor: Int?) { @@ -79,14 +90,9 @@ class ClockViewFactory( controller.largeClock.events.onRegionDarknessChanged(isRegionDark) // Configure font size - val screenSizeCalculator = ScreenSizeCalculator.getInstance() - val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay) - val ratio = - activity.resources.getDimensionPixelSize(R.dimen.screen_preview_height).toFloat() / - screenSize.y.toFloat() controller.largeClock.events.onFontSettingChanged( activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() * - ratio + getRatio() ) clockControllers[clockId] = controller return controller -- cgit v1.2.3