blob: 4f1e2e6009457e74f31019482028641b42cfb648 [file] [log] [blame]
package com.android.dialer.widget;
import com.google.common.annotations.VisibleForTesting;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.os.Bundle;
import android.util.Log;
import com.android.dialer.DialtactsActivity;
import com.android.phone.common.animation.AnimUtils;
import com.android.phone.common.animation.AnimUtils.AnimationCallback;
/**
* Controls the various animated properties of the actionBar: showing/hiding, fading/revealing,
* and collapsing/expanding, and assigns suitable properties to the actionBar based on the
* current state of the UI.
*/
public class ActionBarController {
public static final boolean DEBUG = DialtactsActivity.DEBUG;
public static final String TAG = "ActionBarController";
private static final String KEY_IS_SLID_UP = "key_actionbar_is_slid_up";
private static final String KEY_IS_FADED_OUT = "key_actionbar_is_faded_out";
private static final String KEY_IS_EXPANDED = "key_actionbar_is_expanded";
private ActivityUi mActivityUi;
private SearchEditTextLayout mSearchBox;
private boolean mIsActionBarSlidUp;
private final AnimationCallback mFadeOutCallback = new AnimationCallback() {
@Override
public void onAnimationEnd() {
slideActionBarUp(false);
}
@Override
public void onAnimationCancel() {
slideActionBarUp(false);
}
};
public interface ActivityUi {
public boolean isInSearchUi();
public boolean hasSearchQuery();
public boolean shouldShowActionBar();
public int getActionBarHeight();
public int getActionBarHideOffset();
public void setActionBarHideOffset(int hideOffset);
}
public ActionBarController(ActivityUi activityUi, SearchEditTextLayout searchBox) {
mActivityUi = activityUi;
mSearchBox = searchBox;
}
/**
* @return The offset the action bar is being translated upwards by
*/
public int getHideOffset() {
return mActivityUi.getActionBarHideOffset();
}
/**
* @return Whether or not the action bar is currently showing (both slid down and visible)
*/
public boolean isActionBarShowing() {
return !mIsActionBarSlidUp && !mSearchBox.isFadedOut();
}
/**
* Called when the user has tapped on the collapsed search box, to start a new search query.
*/
public void onSearchBoxTapped() {
if (DEBUG) {
Log.d(TAG, "OnSearchBoxTapped: isInSearchUi " + mActivityUi.isInSearchUi());
}
if (!mActivityUi.isInSearchUi()) {
mSearchBox.expand(true /* animate */, true /* requestFocus */);
}
}
/**
* Called when search UI has been exited for some reason.
*/
public void onSearchUiExited() {
if (DEBUG) {
Log.d(TAG, "OnSearchUIExited: isExpanded " + mSearchBox.isExpanded()
+ " isFadedOut: " + mSearchBox.isFadedOut()
+ " shouldShowActionBar: " + mActivityUi.shouldShowActionBar());
}
if (mSearchBox.isExpanded()) {
mSearchBox.collapse(true /* animate */);
}
if (mSearchBox.isFadedOut()) {
mSearchBox.fadeIn();
}
if (mActivityUi.shouldShowActionBar()) {
slideActionBarDown(false /* animate */);
} else {
slideActionBarUp(false /* animate */);
}
}
/**
* Called to indicate that the user is trying to hide the dialpad. Should be called before
* any state changes have actually occurred.
*/
public void onDialpadDown() {
if (DEBUG) {
Log.d(TAG, "OnDialpadDown: isInSearchUi " + mActivityUi.isInSearchUi()
+ " hasSearchQuery: " + mActivityUi.hasSearchQuery()
+ " isFadedOut: " + mSearchBox.isFadedOut()
+ " isExpanded: " + mSearchBox.isExpanded());
}
if (mActivityUi.isInSearchUi()) {
if (mActivityUi.hasSearchQuery()) {
if (mSearchBox.isFadedOut()) {
mSearchBox.setVisible(true);
}
if (!mSearchBox.isExpanded()) {
mSearchBox.expand(false /* animate */, false /* requestFocus */);
}
slideActionBarDown(true /* animate */);
} else {
mSearchBox.fadeIn();
}
}
}
/**
* Called to indicate that the user is trying to show the dialpad. Should be called before
* any state changes have actually occurred.
*/
public void onDialpadUp() {
if (DEBUG) {
Log.d(TAG, "OnDialpadUp: isInSearchUi " + mActivityUi.isInSearchUi());
}
if (mActivityUi.isInSearchUi()) {
slideActionBarUp(true);
} else {
// From the lists fragment
mSearchBox.fadeOut(mFadeOutCallback);
}
}
public void slideActionBarUp(boolean animate) {
if (DEBUG) {
Log.d(TAG, "Sliding actionBar up - animate: " + animate);
}
if (animate) {
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
final float value = (float) animation.getAnimatedValue();
mActivityUi.setActionBarHideOffset(
(int) (mActivityUi.getActionBarHeight() * value));
}
});
animator.start();
} else {
mActivityUi.setActionBarHideOffset(mActivityUi.getActionBarHeight());
}
mIsActionBarSlidUp = true;
}
public void slideActionBarDown(boolean animate) {
if (DEBUG) {
Log.d(TAG, "Sliding actionBar down - animate: " + animate);
}
if (animate) {
ValueAnimator animator = ValueAnimator.ofFloat(1, 0);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
final float value = (float) animation.getAnimatedValue();
mActivityUi.setActionBarHideOffset(
(int) (mActivityUi.getActionBarHeight() * value));
}
});
animator.start();
} else {
mActivityUi.setActionBarHideOffset(0);
}
mIsActionBarSlidUp = false;
}
public void setAlpha(float alphaValue) {
mSearchBox.animate().alpha(alphaValue).start();
}
/**
* Saves the current state of the action bar into a provided {@link Bundle}
*/
public void saveInstanceState(Bundle outState) {
outState.putBoolean(KEY_IS_SLID_UP, mIsActionBarSlidUp);
outState.putBoolean(KEY_IS_FADED_OUT, mSearchBox.isFadedOut());
outState.putBoolean(KEY_IS_EXPANDED, mSearchBox.isExpanded());
}
/**
* Restores the action bar state from a provided {@link Bundle}
*/
public void restoreInstanceState(Bundle inState) {
mIsActionBarSlidUp = inState.getBoolean(KEY_IS_SLID_UP);
if (mIsActionBarSlidUp) {
slideActionBarUp(false);
} else {
slideActionBarDown(false);
}
final boolean isSearchBoxFadedOut = inState.getBoolean(KEY_IS_FADED_OUT);
if (isSearchBoxFadedOut) {
if (!mSearchBox.isFadedOut()) {
mSearchBox.setVisible(false);
}
} else if (mSearchBox.isFadedOut()) {
mSearchBox.setVisible(true);
}
final boolean isSearchBoxExpanded = inState.getBoolean(KEY_IS_EXPANDED);
if (isSearchBoxExpanded) {
if (!mSearchBox.isExpanded()) {
mSearchBox.expand(false, false);
}
} else if (mSearchBox.isExpanded()) {
mSearchBox.collapse(false);
}
}
@VisibleForTesting
public boolean getIsActionBarSlidUp() {
return mIsActionBarSlidUp;
}
}