OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser; |
| 6 |
| 7 import android.animation.Animator; |
| 8 import android.animation.AnimatorListenerAdapter; |
| 9 import android.animation.ObjectAnimator; |
| 10 import android.animation.ValueAnimator; |
| 11 import android.content.Context; |
| 12 import android.content.res.TypedArray; |
| 13 import android.support.v7.app.ActionBar; |
| 14 import android.util.Property; |
| 15 |
| 16 import com.google.android.apps.chrome.R; |
| 17 |
| 18 /** |
| 19 * This class handles the animation for the contextual menu bar and adds a custo
m |
| 20 * ActionMode.Callback to the menu bar. |
| 21 */ |
| 22 public class ContextualMenuBar { |
| 23 |
| 24 private static final int SLIDE_DURATION_MS = 200; |
| 25 |
| 26 private CustomSelectionActionModeCallback mCustomSelectionActionModeCallback
; |
| 27 private ObjectAnimator mCurrentAnimation = null; |
| 28 private boolean mShowingContextualActionBar = false; |
| 29 private float mTabStripHeight; |
| 30 private final Context mContext; |
| 31 private final ActionBarDelegate mActionBarDelegate; |
| 32 |
| 33 /** Property for animating the top margin of ActionBarDelegate. */ |
| 34 public static final Property<ActionBarDelegate, Integer> TOP_MARGIN_ANIM_PRO
PERTY = |
| 35 new Property<ActionBarDelegate, Integer>(Integer.class, "controlTopM
argin") { |
| 36 @Override |
| 37 public Integer get(ActionBarDelegate delegate) { |
| 38 return delegate.getControlTopMargin(); |
| 39 } |
| 40 @Override |
| 41 public void set(ActionBarDelegate delegate, Integer value) { |
| 42 delegate.setControlTopMargin(value); |
| 43 } |
| 44 }; |
| 45 |
| 46 /** |
| 47 * This is an interface for objects that the contextualMenuBar can use for a
nimating the action |
| 48 * bar. |
| 49 */ |
| 50 public interface ActionBarDelegate { |
| 51 |
| 52 /** |
| 53 * Sets the top margin of the control container. |
| 54 * @param margin The new top margin of the control container. |
| 55 */ |
| 56 public void setControlTopMargin(int margin); |
| 57 |
| 58 /** |
| 59 * @return The top margin of the control container. |
| 60 */ |
| 61 public int getControlTopMargin(); |
| 62 |
| 63 /** |
| 64 * @return The action bar that will be animated in and out. |
| 65 */ |
| 66 public ActionBar getSupportActionBar(); |
| 67 |
| 68 /** |
| 69 * Change the background visibility for the action bar. |
| 70 * @param visible Whether the background should be visible. |
| 71 */ |
| 72 public void setActionBarBackgroundVisibility(boolean visible); |
| 73 } |
| 74 |
| 75 /** |
| 76 * Creates the contextual menu bar and ties it to an action bar using the gi
ven action bar |
| 77 * delegate. |
| 78 * @param context The context which the contextual action menu bar should be
using for accessing |
| 79 * resources. |
| 80 * @param actionBarDelegate The delegate for communicating with the action b
ar while animating |
| 81 * it. |
| 82 */ |
| 83 public ContextualMenuBar(Context context, ActionBarDelegate actionBarDelegat
e) { |
| 84 mActionBarDelegate = actionBarDelegate; |
| 85 mContext = context; |
| 86 mTabStripHeight = mContext.getResources().getDimension(R.dimen.tab_strip
_height); |
| 87 } |
| 88 |
| 89 /** |
| 90 * @return The delegate handling action bar positioning for the contextual m
enu bar. |
| 91 */ |
| 92 public ActionBarDelegate getActionBarDelegate() { |
| 93 return mActionBarDelegate; |
| 94 } |
| 95 |
| 96 /** |
| 97 * Sets the custom ActionMode.Callback |
| 98 * @param customSelectionActionModeCallback |
| 99 */ |
| 100 public void setCustomSelectionActionModeCallback( |
| 101 CustomSelectionActionModeCallback customSelectionActionModeCallback)
{ |
| 102 if (customSelectionActionModeCallback.equals(mCustomSelectionActionModeC
allback)) return; |
| 103 mCustomSelectionActionModeCallback = customSelectionActionModeCallback; |
| 104 mCustomSelectionActionModeCallback.setContextualMenuBar(this); |
| 105 } |
| 106 |
| 107 /** |
| 108 * @return The custom ActionMode.Callback. |
| 109 */ |
| 110 public CustomSelectionActionModeCallback getCustomSelectionActionModeCallbac
k() { |
| 111 return mCustomSelectionActionModeCallback; |
| 112 } |
| 113 |
| 114 /** |
| 115 * @return The current action bar height. |
| 116 */ |
| 117 private int queryCurrentActionBarHeight() { |
| 118 ActionBar actionBar = mActionBarDelegate.getSupportActionBar(); |
| 119 if (actionBar != null) return actionBar.getHeight(); |
| 120 |
| 121 TypedArray styledAttributes = |
| 122 mContext.obtainStyledAttributes(new int[] {R.attr.actionBarSize}
); |
| 123 int height = styledAttributes.getDimensionPixelSize(0, 0); |
| 124 styledAttributes.recycle(); |
| 125 return height; |
| 126 } |
| 127 |
| 128 /** |
| 129 * Show controls after orientation change if previously visible. |
| 130 */ |
| 131 public void showControlsOnOrientationChange() { |
| 132 if (mShowingContextualActionBar && mCurrentAnimation == null) { |
| 133 showControls(); |
| 134 } |
| 135 } |
| 136 |
| 137 /** |
| 138 * Animation for the textview if the action bar is visible. |
| 139 */ |
| 140 public void showControls() { |
| 141 if (mCurrentAnimation != null) mCurrentAnimation.cancel(); |
| 142 |
| 143 mCurrentAnimation = ObjectAnimator.ofInt(mActionBarDelegate, TOP_MARGIN_
ANIM_PROPERTY, |
| 144 (int) (Math.max(0, queryCurrentActionBarHeight() - mTabStripHeig
ht))).setDuration( |
| 145 SLIDE_DURATION_MS); |
| 146 |
| 147 mCurrentAnimation.addListener(new AnimatorListenerAdapter() { |
| 148 @Override |
| 149 public void onAnimationEnd(Animator animation) { |
| 150 mCurrentAnimation = null; |
| 151 } |
| 152 }); |
| 153 |
| 154 mCurrentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateList
ener() { |
| 155 @Override |
| 156 public void onAnimationUpdate(ValueAnimator animation) { |
| 157 ActionBar actionBar = mActionBarDelegate.getSupportActionBar(); |
| 158 if (actionBar != null) { |
| 159 animation.setIntValues((int) (Math.max(0, |
| 160 queryCurrentActionBarHeight() - mTabStripHeight))); |
| 161 } |
| 162 } |
| 163 }); |
| 164 |
| 165 mActionBarDelegate.setActionBarBackgroundVisibility(true); |
| 166 mCurrentAnimation.start(); |
| 167 mShowingContextualActionBar = true; |
| 168 } |
| 169 |
| 170 /** |
| 171 * Hide animation for the textview if the action bar is not visible. |
| 172 */ |
| 173 public void hideControls() { |
| 174 if (mCurrentAnimation != null) mCurrentAnimation.cancel(); |
| 175 |
| 176 mCurrentAnimation = ObjectAnimator.ofInt(mActionBarDelegate, TOP_MARGIN_
ANIM_PROPERTY, |
| 177 0).setDuration(SLIDE_DURATION_MS); |
| 178 |
| 179 mCurrentAnimation.addListener(new AnimatorListenerAdapter() { |
| 180 @Override |
| 181 public void onAnimationEnd(Animator animation) { |
| 182 mCurrentAnimation = null; |
| 183 mActionBarDelegate.setActionBarBackgroundVisibility(false); |
| 184 } |
| 185 }); |
| 186 |
| 187 mCurrentAnimation.start(); |
| 188 mShowingContextualActionBar = false; |
| 189 } |
| 190 } |
OLD | NEW |