diff options
| author | 2020-04-17 17:11:36 -0400 | |
|---|---|---|
| committer | 2020-04-21 08:27:55 -0400 | |
| commit | f4b870bc671a10ae6000b1ed2b360dcf745bbbe4 (patch) | |
| tree | fcdfcfdc343dd86dc6e93a89e1ce8a5570170cb8 | |
| parent | e66ac51ea3d0e5915e8d358030fe61924d62c6f1 (diff) | |
Controls UI - Motion for activities
Transition between control activities with animations. Transition between
GlobalActionsDialog and controls activities with the same
animations. Load async data into RecyclerViews in a separate animation
but controlling alpha values on the view
Bug: 154158092
Test: visual
Change-Id: I77c192d5b23a844900f4f2be128687d6314a1baf
10 files changed, 322 insertions, 60 deletions
diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml index ae57563cfb09..6da96d10c253 100644 --- a/packages/SystemUI/res/layout/controls_management.xml +++ b/packages/SystemUI/res/layout/controls_management.xml @@ -17,6 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/controls_management_root" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 599ed1696ec9..7cefa0c498d5 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1014,6 +1014,9 @@ <!-- Margins at the left and right of the power menu and home controls widgets. --> <dimen name="global_actions_side_margin">16dp</dimen> + <!-- Amount to shift the layout when exiting/entering for controls activities --> + <dimen name="global_actions_controls_y_translation">20dp</dimen> + <!-- The maximum offset in either direction that elements are moved horizontally to prevent burn-in on AOD. --> <dimen name="burn_in_prevention_offset_x">8dp</dimen> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 7e24f5dbbd50..4ed819e4925b 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -663,8 +663,13 @@ <!-- Controls styles --> <style name="Theme.ControlsManagement" parent="@android:style/Theme.DeviceDefault.NoActionBar"> + <item name="android:windowActivityTransitions">true</item> + <item name="android:windowContentTransitions">false</item> <item name="android:windowIsTranslucent">false</item> - <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item> + <item name="android:windowBackground">@android:color/black</item> + <item name="android:colorBackground">@android:color/black</item> + <item name="android:windowAnimationStyle">@null</item> + <item name="android:statusBarColor">@*android:color/transparent</item> </style> <style name="TextAppearance.Control"> diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt new file mode 100644 index 000000000000..4ca47d1d41ba --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.controls.management + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.AnimatorSet +import android.animation.ObjectAnimator +import android.annotation.IdRes +import android.content.Intent + +import android.transition.Transition +import android.transition.TransitionValues +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.view.Window + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent + +import com.android.systemui.Interpolators +import com.android.systemui.R + +import com.android.systemui.controls.ui.ControlsUiController + +object ControlsAnimations { + + private const val ALPHA_EXIT_DURATION = 167L + private const val ALPHA_ENTER_DELAY = ALPHA_EXIT_DURATION + private const val ALPHA_ENTER_DURATION = 350L - ALPHA_ENTER_DELAY + + private const val Y_TRANSLATION_EXIT_DURATION = 183L + private const val Y_TRANSLATION_ENTER_DELAY = Y_TRANSLATION_EXIT_DURATION - ALPHA_ENTER_DELAY + private const val Y_TRANSLATION_ENTER_DURATION = 400L - Y_TRANSLATION_EXIT_DURATION + private var translationY: Float = -1f + + /** + * Setup an activity to handle enter/exit animations. [view] should be the root of the content. + * Fade and translate together. + */ + fun observerForAnimations(view: ViewGroup, window: Window, intent: Intent): LifecycleObserver { + return object : LifecycleObserver { + var showAnimation = intent.getBooleanExtra(ControlsUiController.EXTRA_ANIMATE, false) + + init { + // Must flag the parent group to move it all together, and set the initial + // transitionAlpha to 0.0f. This property is reserved for fade animations. + view.setTransitionGroup(true) + view.transitionAlpha = 0.0f + + if (translationY == -1f) { + translationY = view.context.resources.getDimensionPixelSize( + R.dimen.global_actions_controls_y_translation).toFloat() + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_START) + fun setup() { + with(window) { + allowEnterTransitionOverlap = true + enterTransition = enterWindowTransition(view.getId()) + exitTransition = exitWindowTransition(view.getId()) + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) + fun enterAnimation() { + if (showAnimation) { + ControlsAnimations.enterAnimation(view).start() + showAnimation = false + } + } + } + } + + fun enterAnimation(view: View): Animator { + Log.d(ControlsUiController.TAG, "Enter animation for $view") + + view.transitionAlpha = 0.0f + view.alpha = 1.0f + + view.translationY = translationY + + val alphaAnimator = ObjectAnimator.ofFloat(view, "transitionAlpha", 0.0f, 1.0f).apply { + interpolator = Interpolators.DECELERATE_QUINT + startDelay = ALPHA_ENTER_DELAY + duration = ALPHA_ENTER_DURATION + } + + val yAnimator = ObjectAnimator.ofFloat(view, "translationY", 0.0f).apply { + interpolator = Interpolators.DECELERATE_QUINT + startDelay = Y_TRANSLATION_ENTER_DURATION + duration = Y_TRANSLATION_ENTER_DURATION + } + + return AnimatorSet().apply { + playTogether(alphaAnimator, yAnimator) + } + } + + /** + * Properly handle animations originating from dialogs. Activity transitions require + * transitioning between two activities, so expose this method for dialogs to animate + * on exit. + */ + @JvmStatic + fun exitAnimation(view: View, onEnd: Runnable? = null): Animator { + Log.d(ControlsUiController.TAG, "Exit animation for $view") + + val alphaAnimator = ObjectAnimator.ofFloat(view, "transitionAlpha", 0.0f).apply { + interpolator = Interpolators.ACCELERATE + duration = ALPHA_EXIT_DURATION + } + + view.translationY = 0.0f + val yAnimator = ObjectAnimator.ofFloat(view, "translationY", -translationY).apply { + interpolator = Interpolators.ACCELERATE + duration = Y_TRANSLATION_EXIT_DURATION + } + + return AnimatorSet().apply { + playTogether(alphaAnimator, yAnimator) + onEnd?.let { + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + it.run() + } + }) + } + } + } + + fun enterWindowTransition(@IdRes id: Int) = + WindowTransition({ view: View -> enterAnimation(view) }).apply { + addTarget(id) + } + + fun exitWindowTransition(@IdRes id: Int) = + WindowTransition({ view: View -> exitAnimation(view) }).apply { + addTarget(id) + } +} + +/** + * In order to animate, at least one property must be marked on each view that should move. + * Setting "item" is just a flag to indicate that it should move by the animator. + */ +class WindowTransition( + val animator: (view: View) -> Animator +) : Transition() { + override fun captureStartValues(tv: TransitionValues) { + tv.values["item"] = 0.0f + } + + override fun captureEndValues(tv: TransitionValues) { + tv.values["item"] = 1.0f + } + + override fun createAnimator( + sceneRoot: ViewGroup, + startValues: TransitionValues?, + endValues: TransitionValues? + ): Animator? = animator(startValues!!.view) +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index ee1ce7ab3d83..273e47c1c094 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -16,11 +16,12 @@ package com.android.systemui.controls.management -import android.app.Activity +import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent import android.os.Bundle import android.view.View +import android.view.ViewGroup import android.view.ViewStub import android.widget.Button import android.widget.TextView @@ -32,6 +33,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.settings.CurrentUserTracker +import com.android.systemui.util.LifecycleActivity import javax.inject.Inject /** @@ -40,7 +42,7 @@ import javax.inject.Inject class ControlsEditingActivity @Inject constructor( private val controller: ControlsControllerImpl, broadcastDispatcher: BroadcastDispatcher -) : Activity() { +) : LifecycleActivity() { companion object { private const val TAG = "ControlsEditingActivity" @@ -92,6 +94,15 @@ class ControlsEditingActivity @Inject constructor( private fun bindViews() { setContentView(R.layout.controls_management) + + getLifecycle().addObserver( + ControlsAnimations.observerForAnimations( + requireViewById<ViewGroup>(R.id.controls_management_root), + window, + intent + ) + ) + requireViewById<ViewStub>(R.id.stub).apply { layoutResource = R.layout.controls_management_editing inflate() @@ -113,8 +124,8 @@ class ControlsEditingActivity @Inject constructor( putExtras(this@ControlsEditingActivity.intent) putExtra(ControlsFavoritingActivity.EXTRA_SINGLE_STRUCTURE, true) } - startActivity(intent) - finish() + startActivity(intent, ActivityOptions + .makeSceneTransitionAnimation(this@ControlsEditingActivity).toBundle()) } } @@ -151,26 +162,38 @@ class ControlsEditingActivity @Inject constructor( val controls = controller.getFavoritesForStructure(component, structure) model = FavoritesModel(component, controls, favoritesModelCallback) val elevation = resources.getFloat(R.dimen.control_card_elevation) - val adapter = ControlAdapter(elevation) - val recycler = requireViewById<RecyclerView>(R.id.list) + val recyclerView = requireViewById<RecyclerView>(R.id.list) + recyclerView.alpha = 0.0f + val adapter = ControlAdapter(elevation).apply { + registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { + var hasAnimated = false + override fun onChanged() { + if (!hasAnimated) { + hasAnimated = true + ControlsAnimations.enterAnimation(recyclerView).start() + } + } + }) + } + val margin = resources .getDimensionPixelSize(R.dimen.controls_card_margin) val itemDecorator = MarginItemDecorator(margin, margin) - recycler.apply { + recyclerView.apply { this.adapter = adapter - layoutManager = GridLayoutManager(recycler.context, 2).apply { + layoutManager = GridLayoutManager(recyclerView.context, 2).apply { spanSizeLookup = adapter.spanSizeLookup } addItemDecoration(itemDecorator) } adapter.changeModel(model) model.attachAdapter(adapter) - ItemTouchHelper(model.itemTouchHelperCallback).attachToRecyclerView(recycler) + ItemTouchHelper(model.itemTouchHelperCallback).attachToRecyclerView(recyclerView) } override fun onDestroy() { currentUserTracker.stopTracking() super.onDestroy() } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 6f34deeb8547..4a3470507010 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -16,7 +16,7 @@ package com.android.systemui.controls.management -import android.app.Activity +import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent import android.content.res.Configuration @@ -41,6 +41,7 @@ import com.android.systemui.controls.controller.ControlsControllerImpl import com.android.systemui.controls.controller.StructureInfo import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.settings.CurrentUserTracker +import com.android.systemui.util.LifecycleActivity import java.text.Collator import java.util.concurrent.Executor import java.util.function.Consumer @@ -51,7 +52,7 @@ class ControlsFavoritingActivity @Inject constructor( private val controller: ControlsControllerImpl, private val listingController: ControlsListingController, broadcastDispatcher: BroadcastDispatcher -) : Activity() { +) : LifecycleActivity() { companion object { private const val TAG = "ControlsFavoritingActivity" @@ -115,6 +116,7 @@ class ControlsFavoritingActivity @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val collator = Collator.getInstance(resources.configuration.locales[0]) comparator = compareBy(collator) { it.structureName } appName = intent.getCharSequenceExtra(EXTRA_APP) @@ -174,12 +176,17 @@ class ControlsFavoritingActivity @Inject constructor( pageIndicator.setLocation(0f) pageIndicator.visibility = if (listOfStructures.size > 1) View.VISIBLE else View.GONE + + ControlsAnimations.enterAnimation(pageIndicator).start() + ControlsAnimations.enterAnimation(structurePager).start() } }) } } private fun setUpPager() { + structurePager.alpha = 0.0f + pageIndicator.alpha = 0.0f structurePager.apply { adapter = StructureAdapter(emptyList()) registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { @@ -203,6 +210,15 @@ class ControlsFavoritingActivity @Inject constructor( private fun bindViews() { setContentView(R.layout.controls_management) + + getLifecycle().addObserver( + ControlsAnimations.observerForAnimations( + requireViewById<ViewGroup>(R.id.controls_management_root), + window, + intent + ) + ) + requireViewById<ViewStub>(R.id.stub).apply { layoutResource = R.layout.controls_management_favorites inflate() @@ -278,7 +294,8 @@ class ControlsFavoritingActivity @Inject constructor( val i = Intent() i.setComponent( ComponentName(context, ControlsProviderSelectorActivity::class.java)) - context.startActivity(i) + startActivity(i, ActivityOptions + .makeSceneTransitionAnimation(this@ControlsFavoritingActivity).toBundle()) } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index 3be59009f531..59a8b32a10e7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -16,15 +16,18 @@ package com.android.systemui.controls.management +import android.app.ActivityOptions import android.content.ComponentName import android.content.Intent import android.os.Bundle import android.view.LayoutInflater +import android.view.ViewGroup import android.view.ViewStub import android.widget.Button import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlsController @@ -66,12 +69,23 @@ class ControlsProviderSelectorActivity @Inject constructor( super.onCreate(savedInstanceState) setContentView(R.layout.controls_management) + + getLifecycle().addObserver( + ControlsAnimations.observerForAnimations( + requireViewById<ViewGroup>(R.id.controls_management_root), + window, + intent + ) + ) + requireViewById<ViewStub>(R.id.stub).apply { layoutResource = R.layout.controls_management_apps inflate() } recyclerView = requireViewById(R.id.list) + recyclerView.alpha = 0.0f + recyclerView.layoutManager = LinearLayoutManager(applicationContext) recyclerView.adapter = AppAdapter( backExecutor, executor, @@ -80,11 +94,21 @@ class ControlsProviderSelectorActivity @Inject constructor( LayoutInflater.from(this), ::launchFavoritingActivity, FavoritesRenderer(resources, controlsController::countFavoritesForComponent), - resources) - recyclerView.layoutManager = LinearLayoutManager(applicationContext) + resources).apply { + registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { + var hasAnimated = false + override fun onChanged() { + if (!hasAnimated) { + hasAnimated = true + ControlsAnimations.enterAnimation(recyclerView).start() + } + } + }) + } - requireViewById<TextView>(R.id.title).text = - resources.getText(R.string.controls_providers_title) + requireViewById<TextView>(R.id.title).apply { + text = resources.getText(R.string.controls_providers_title) + } requireViewById<Button>(R.id.done).setOnClickListener { this@ControlsProviderSelectorActivity.finishAffinity() @@ -98,7 +122,7 @@ class ControlsProviderSelectorActivity @Inject constructor( * @param component a component name for a [ControlsProviderService] */ fun launchFavoritingActivity(component: ComponentName?) { - backExecutor.execute { + executor.execute { component?.let { val intent = Intent(applicationContext, ControlsFavoritingActivity::class.java) .apply { @@ -107,7 +131,7 @@ class ControlsProviderSelectorActivity @Inject constructor( putExtra(Intent.EXTRA_COMPONENT_NAME, it) flags = Intent.FLAG_ACTIVITY_SINGLE_TOP } - startActivity(intent) + startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt index 61a1a986c091..aed7cd316bc7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt @@ -26,9 +26,10 @@ interface ControlsUiController { companion object { public const val TAG = "ControlsUiController" + public const val EXTRA_ANIMATE = "extra_animate" } - fun show(parent: ViewGroup) + fun show(parent: ViewGroup, dismissGlobalActions: Runnable) fun hide() fun onRefreshState(componentName: ComponentName, controls: List<Control>) fun onActionResponse( diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 2adfb1bd6d4f..cfd8df059567 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -85,7 +85,7 @@ class ControlsUiControllerImpl @Inject constructor ( private const val PREF_STRUCTURE = "controls_structure" private const val USE_PANELS = "systemui.controls_use_panel" - private const val FADE_IN_MILLIS = 225L + private const val FADE_IN_MILLIS = 200L private val EMPTY_COMPONENT = ComponentName("", "") private val EMPTY_STRUCTURE = StructureInfo( @@ -104,6 +104,7 @@ class ControlsUiControllerImpl @Inject constructor ( private var popup: ListPopupWindow? = null private var activeDialog: Dialog? = null private var hidden = true + private lateinit var dismissGlobalActions: Runnable override val available: Boolean get() = controlsController.get().available @@ -134,9 +135,10 @@ class ControlsUiControllerImpl @Inject constructor ( } } - override fun show(parent: ViewGroup) { + override fun show(parent: ViewGroup, dismissGlobalActions: Runnable) { Log.d(ControlsUiController.TAG, "show()") this.parent = parent + this.dismissGlobalActions = dismissGlobalActions hidden = false allStructures = controlsController.get().getFavorites() @@ -169,7 +171,7 @@ class ControlsUiControllerImpl @Inject constructor ( fadeAnim.setDuration(FADE_IN_MILLIS) fadeAnim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - show(parent) + show(parent, dismissGlobalActions) val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f) showAnim.setInterpolator(DecelerateInterpolator(1.0f)) showAnim.setDuration(FADE_IN_MILLIS) @@ -256,9 +258,10 @@ class ControlsUiControllerImpl @Inject constructor ( } private fun startActivity(context: Context, intent: Intent) { - val closeDialog = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) - context.sendBroadcast(closeDialog) + // Force animations when transitioning from a dialog to an activity + intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true) context.startActivity(intent) + dismissGlobalActions.run() } private fun showControlsView(items: List<SelectionItem>) { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 322660521ee0..b88350f52678 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -110,6 +110,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.controls.ControlsServiceInfo; import com.android.systemui.controls.controller.ControlsController; +import com.android.systemui.controls.management.ControlsAnimations; import com.android.systemui.controls.management.ControlsListingController; import com.android.systemui.controls.ui.ControlsUiController; import com.android.systemui.dagger.qualifiers.Background; @@ -1815,7 +1816,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, case MESSAGE_DISMISS: if (mDialog != null) { if (SYSTEM_DIALOG_REASON_DREAM.equals(msg.obj)) { - mDialog.dismissImmediately(); + mDialog.completeDismiss(); } else { mDialog.dismiss(); } @@ -2200,50 +2201,55 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return WindowInsets.CONSUMED; }); if (mControlsUiController != null) { - mControlsUiController.show(mControlsView); + mControlsUiController.show(mControlsView, this::dismissForControlsActivity); } } @Override public void dismiss() { + dismissWithAnimation(() -> { + mGlobalActionsLayout.setTranslationX(0); + mGlobalActionsLayout.setTranslationY(0); + mGlobalActionsLayout.setAlpha(1); + mGlobalActionsLayout.animate() + .alpha(0) + .translationX(mGlobalActionsLayout.getAnimationOffsetX()) + .translationY(mGlobalActionsLayout.getAnimationOffsetY()) + .setDuration(550) + .withEndAction(this::completeDismiss) + .setInterpolator(new LogAccelerateInterpolator()) + .setUpdateListener(animation -> { + float animatedValue = 1f - animation.getAnimatedFraction(); + int alpha = (int) (animatedValue * mScrimAlpha * 255); + mBackgroundDrawable.setAlpha(alpha); + mDepthController.updateGlobalDialogVisibility(animatedValue, + mGlobalActionsLayout); + }) + .start(); + }); + } + + private void dismissForControlsActivity() { + dismissWithAnimation(() -> { + ViewGroup root = (ViewGroup) mGlobalActionsLayout.getRootView(); + ControlsAnimations.exitAnimation(root, this::completeDismiss).start(); + }); + } + + void dismissWithAnimation(Runnable animation) { if (!mShowing) { return; } mShowing = false; - if (mControlsUiController != null) mControlsUiController.hide(); - mGlobalActionsLayout.setTranslationX(0); - mGlobalActionsLayout.setTranslationY(0); - mGlobalActionsLayout.setAlpha(1); - mGlobalActionsLayout.animate() - .alpha(0) - .translationX(mGlobalActionsLayout.getAnimationOffsetX()) - .translationY(mGlobalActionsLayout.getAnimationOffsetY()) - .setDuration(550) - .withEndAction(this::completeDismiss) - .setInterpolator(new LogAccelerateInterpolator()) - .setUpdateListener(animation -> { - float animatedValue = 1f - animation.getAnimatedFraction(); - int alpha = (int) (animatedValue * mScrimAlpha * 255); - mBackgroundDrawable.setAlpha(alpha); - mDepthController.updateGlobalDialogVisibility(animatedValue, - mGlobalActionsLayout); - }) - .start(); - dismissPanel(); - dismissOverflow(); - resetOrientation(); + animation.run(); } - void dismissImmediately() { + private void completeDismiss() { mShowing = false; - if (mControlsUiController != null) mControlsUiController.hide(); + resetOrientation(); dismissPanel(); dismissOverflow(); - resetOrientation(); - completeDismiss(); - } - - private void completeDismiss() { + if (mControlsUiController != null) mControlsUiController.hide(); mNotificationShadeWindowController.setForceHasTopUi(mHadTopUi); mDepthController.updateGlobalDialogVisibility(0, null /* view */); super.dismiss(); @@ -2304,7 +2310,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, initializeLayout(); mGlobalActionsLayout.updateList(); if (mControlsUiController != null) { - mControlsUiController.show(mControlsView); + mControlsUiController.show(mControlsView, this::dismissForControlsActivity); } } @@ -2343,10 +2349,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, && mControlsUiController.getAvailable() && !mControlsServiceInfos.isEmpty(); } - // TODO: Remove legacy layout XML and classes. protected boolean shouldUseControlsLayout() { // always use new controls layout return true; } -}
\ No newline at end of file +} |