Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1354)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java

Issue 2839673002: 🏠 Polish bottom sheet content transitions (Closed)
Patch Set: end animation immediately if no previous content Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/android/java/res/layout/bottom_control_container.xml ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index 8f4e4426c7cc8fe73e065d5eb313ad04adb01a33..ede7e626e835e6cc31653b71692edf5e9def8100 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.widget.bottomsheet;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -20,6 +21,7 @@ import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -49,6 +51,8 @@ import org.chromium.content_public.browser.LoadUrlParams;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
/**
* This class defines the bottom sheet that has multiple states and a persistently showing toolbar.
@@ -86,6 +90,9 @@ public class BottomSheet
*/
private static final long BASE_ANIMATION_DURATION_MS = 218;
+ /** The amount of time it takes to transition sheet content in or out. */
+ private static final long TRANSITION_DURATION_MS = 150;
+
/**
* The fraction of the way to the next state the sheet must be swiped to animate there when
* released. This is the value used when there are 3 active states. A smaller value here means
@@ -140,8 +147,8 @@ public class BottomSheet
/** The animator used to move the sheet to a fixed state when released by the user. */
private ValueAnimator mSettleAnimator;
- /** The animator used for the toolbar fades. */
- private ValueAnimator mToolbarFadeAnimator;
+ /** The animator set responsible for swapping the bottom sheet content. */
+ private AnimatorSet mContentSwapAnimatorSet;
/** The height of the toolbar. */
private float mToolbarHeight;
@@ -557,7 +564,7 @@ public class BottomSheet
LayoutParams placeHolderParams =
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mPlaceholder.setBackgroundColor(
- ApiCompatibilityUtils.getColor(getResources(), android.R.color.white));
+ ApiCompatibilityUtils.getColor(getResources(), R.color.default_primary_color));
mBottomSheetContentContainer.addView(mPlaceholder, placeHolderParams);
mToolbarHolder = (FrameLayout) mControlContainer.findViewById(R.id.toolbar_holder);
@@ -645,83 +652,89 @@ public class BottomSheet
* Show content in the bottom sheet's content area.
* @param content The {@link BottomSheetContent} to show.
*/
- public void showContent(BottomSheetContent content) {
+ public void showContent(final BottomSheetContent content) {
// If the desired content is already showing, do nothing.
if (mSheetContent == content) return;
- View newToolbar = content.getToolbarView();
- View oldToolbar = null;
-
- if (mSheetContent != null) {
- oldToolbar = mSheetContent.getToolbarView();
- mBottomSheetContentContainer.removeView(mSheetContent.getContentView());
- mSheetContent = null;
- }
-
mBottomSheetContentContainer.removeView(mPlaceholder);
- mSheetContent = content;
- mBottomSheetContentContainer.addView(mSheetContent.getContentView());
- doToolbarSwap(newToolbar, oldToolbar);
+ View newToolbar =
+ content.getToolbarView() != null ? content.getToolbarView() : mDefaultToolbarView;
+ View oldToolbar = mSheetContent != null && mSheetContent.getToolbarView() != null
+ ? mSheetContent.getToolbarView()
+ : mDefaultToolbarView;
+ View oldContent = mSheetContent != null ? mSheetContent.getContentView() : null;
- for (BottomSheetObserver o : mObservers) {
- o.onSheetContentChanged(mSheetContent);
- }
- }
+ // If an animation is already running, end it.
+ if (mContentSwapAnimatorSet != null) mContentSwapAnimatorSet.end();
- /**
- * Fade between a new toolbar and the old toolbar to be shown. A null parameter can be used to
- * refer to the default omnibox toolbar. Normally, the new toolbar is attached to the toolbar
- * container and faded in. In the case of the default toolbar, the old toolbar is faded out.
- * This is because the default toolbar is always attached to the view hierarchy and sits behind
- * the attach point for the other toolbars.
- * @param newToolbar The toolbar that will be shown.
- * @param oldToolbar The toolbar being replaced.
- */
- private void doToolbarSwap(View newToolbar, View oldToolbar) {
- if (mToolbarFadeAnimator != null) mToolbarFadeAnimator.end();
-
- final View targetToolbar = newToolbar != null ? newToolbar : mDefaultToolbarView;
- final View currentToolbar = oldToolbar != null ? oldToolbar : mDefaultToolbarView;
-
- if (targetToolbar == currentToolbar) return;
-
- if (targetToolbar != mDefaultToolbarView) {
- mToolbarHolder.addView(targetToolbar);
- targetToolbar.setAlpha(0f);
- } else {
- targetToolbar.setVisibility(View.VISIBLE);
- targetToolbar.setAlpha(1f);
- }
-
- mToolbarFadeAnimator = ObjectAnimator.ofFloat(0, 1);
- mToolbarFadeAnimator.setDuration(BASE_ANIMATION_DURATION_MS);
- mToolbarFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animator) {
- if (targetToolbar == mDefaultToolbarView) {
- currentToolbar.setAlpha(1f - animator.getAnimatedFraction());
- } else {
- targetToolbar.setAlpha(animator.getAnimatedFraction());
- }
- }
- });
- mToolbarFadeAnimator.addListener(new AnimatorListenerAdapter() {
+ List<Animator> animators = new ArrayList<>();
+ mContentSwapAnimatorSet = new AnimatorSet();
+ mContentSwapAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- targetToolbar.setAlpha(1f);
- currentToolbar.setAlpha(0f);
- if (currentToolbar != mDefaultToolbarView) {
- mToolbarHolder.removeView(currentToolbar);
- } else {
- currentToolbar.setVisibility(View.GONE);
+ mSheetContent = content;
+ for (BottomSheetObserver o : mObservers) {
+ o.onSheetContentChanged(content);
}
- mToolbarFadeAnimator = null;
updateHandleTint();
+ mContentSwapAnimatorSet = null;
}
});
- mToolbarFadeAnimator.start();
+ // For the toolbar transition, make sure we don't detach the default toolbar view.
+ animators.add(getViewTransitionAnimator(
+ newToolbar, oldToolbar, mToolbarHolder, mDefaultToolbarView != oldToolbar));
+ animators.add(getViewTransitionAnimator(
+ content.getContentView(), oldContent, mBottomSheetContentContainer, true));
+
+ mContentSwapAnimatorSet.playTogether(animators);
+ mContentSwapAnimatorSet.start();
+
+ // If the existing content is null, end the animation immediately.
+ if (mSheetContent == null) mContentSwapAnimatorSet.end();
+ }
+
+ /**
+ * Creates a transition animation between two views. The old view is faded out completely
+ * before the new view is faded in. There is an option to detach the old view or not.
+ * @param newView The new view to transition to.
+ * @param oldView The old view to transition from.
+ * @param detachOldView Whether or not to detach the old view once faded out.
+ * @return An animator that runs the specified animation.
+ */
+ private Animator getViewTransitionAnimator(final View newView, final View oldView,
+ final ViewGroup parent, final boolean detachOldView) {
+ if (newView == oldView) return null;
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ List<Animator> animators = new ArrayList<>();
+
+ // Fade out the old view.
+ if (oldView != null) {
+ ValueAnimator fadeOutAnimator = ObjectAnimator.ofFloat(oldView, View.ALPHA, 0);
+ fadeOutAnimator.setDuration(TRANSITION_DURATION_MS);
+ fadeOutAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (detachOldView && oldView.getParent() != null) {
+ parent.removeView(oldView);
+ }
+ }
+ });
+ animators.add(fadeOutAnimator);
+ }
+
+ // Fade in the new view.
+ if (parent != newView.getParent()) parent.addView(newView);
+ newView.setAlpha(0);
+ ValueAnimator fadeInAnimator = ObjectAnimator.ofFloat(newView, View.ALPHA, 1);
+ fadeInAnimator.setDuration(TRANSITION_DURATION_MS);
+ animators.add(fadeInAnimator);
+
+ animatorSet.playSequentially(animators);
+
+ return animatorSet;
}
/**
« no previous file with comments | « chrome/android/java/res/layout/bottom_control_container.xml ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698