diff options
Diffstat (limited to 'src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java')
-rw-r--r-- | src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java | 132 |
1 files changed, 130 insertions, 2 deletions
diff --git a/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java b/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java index 63ed0a45..3e32c7f2 100644 --- a/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java +++ b/src/com/android/packageinstaller/permission/ui/PermissionConfirmationViewHandler.java @@ -1,12 +1,18 @@ package com.android.packageinstaller.permission.ui; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; import android.content.Context; import android.graphics.drawable.Icon; import android.os.Handler; +import android.os.Message; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; import android.widget.Button; import android.widget.ImageView; import android.widget.ScrollView; @@ -15,10 +21,15 @@ import android.widget.TextView; import com.android.packageinstaller.R; public abstract class PermissionConfirmationViewHandler implements - View.OnClickListener { + Handler.Callback, + View.OnClickListener, + ViewTreeObserver.OnScrollChangedListener { public static final int MODE_HORIZONTAL_BUTTONS = 0; public static final int MODE_VERTICAL_BUTTONS = 1; + private static final int MSG_HIDE_BUTTON_BAR = 1001; + private static final long HIDE_ANIM_DURATION = 500; + private View mRoot; private TextView mCurrentPageText; private ImageView mIcon; @@ -34,6 +45,13 @@ public abstract class PermissionConfirmationViewHandler implements private Context mContext; + private Handler mHideHandler; + private Interpolator mInterpolator; + private float mButtonBarFloatingHeight; + private ObjectAnimator mButtonBarAnimator; + private float mCurrentTranslation; + private boolean mHiddenBefore; + // TODO: Move these into a builder public abstract void onAllow(); public abstract void onDeny(); @@ -74,6 +92,12 @@ public abstract class PermissionConfirmationViewHandler implements mVerticalDeny.setOnClickListener(this); mVerticalDenyDoNotAskAgain.setOnClickListener(this); + mInterpolator = AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.fast_out_slow_in); + mButtonBarFloatingHeight = mContext.getResources().getDimension( + R.dimen.conf_diag_floating_height); + mHideHandler = new Handler(this); + return mRoot; } @@ -102,7 +126,6 @@ public abstract class PermissionConfirmationViewHandler implements } else { mIcon.setVisibility(View.INVISIBLE); } - mMessage.setText(getMessage()); switch (getButtonBarMode()) { @@ -127,6 +150,43 @@ public abstract class PermissionConfirmationViewHandler implements } mScrollingContainer.scrollTo(0, 0); + + mScrollingContainer.getViewTreeObserver().addOnScrollChangedListener(this); + + mRoot.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + // Setup Button animation. + // pop the button bar back to full height, stop all animation + if (mButtonBarAnimator != null) { + mButtonBarAnimator.cancel(); + } + + // In order to fake the buttons peeking at the bottom, need to do set the + // padding properly. + if (mContent.getPaddingBottom() != mButtonBarContainer.getHeight()) { + mContent.setPadding(0, 0, 0, mButtonBarContainer.getHeight()); + } + + // stop any calls to hide the button bar in the future + mHideHandler.removeMessages(MSG_HIDE_BUTTON_BAR); + mHiddenBefore = false; + + // determine which mode the scrolling should work at. + if (mContent.getHeight() > mScrollingContainer.getHeight()) { + mButtonBarContainer.setTranslationZ(mButtonBarFloatingHeight); + mHideHandler.sendEmptyMessageDelayed(MSG_HIDE_BUTTON_BAR, 3000); + generateButtonBarAnimator(mButtonBarContainer.getHeight(), 0, 0, + mButtonBarFloatingHeight, 1000); + } else { + mButtonBarContainer.setTranslationY(0); + mButtonBarContainer.setTranslationZ(0); + } + mRoot.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + }); + } @Override @@ -146,4 +206,72 @@ public abstract class PermissionConfirmationViewHandler implements break; } } + + @Override + public boolean handleMessage (Message msg) { + switch (msg.what) { + case MSG_HIDE_BUTTON_BAR: + hideButtonBar(); + return true; + } + return false; + } + + @Override + public void onScrollChanged() { + mHideHandler.removeMessages(MSG_HIDE_BUTTON_BAR); + hideButtonBar(); + } + + private void hideButtonBar() { + // get the offset to the top of the button bar + int offset = mScrollingContainer.getHeight() + mButtonBarContainer.getHeight() - + mContent.getHeight() + Math.max(mScrollingContainer.getScrollY(), 0); + int translationY = offset > 0 ? mButtonBarContainer.getHeight() - offset : + mButtonBarContainer.getHeight(); + + if (!mHiddenBefore || mButtonBarAnimator == null) { + // hasn't hidden the bar yet, just hide now to the right height + generateButtonBarAnimator( + mButtonBarContainer.getTranslationY(), translationY, + mButtonBarFloatingHeight, 0, HIDE_ANIM_DURATION); + } else if (mButtonBarAnimator.isRunning()) { + // we are animating the button bar closing, change to animate to the right place + if (Math.abs(mCurrentTranslation - translationY) > 1e-2f) { + mButtonBarAnimator.cancel(); // stop current animation + + if (Math.abs(mButtonBarContainer.getTranslationY() - translationY) > 1e-2f) { + long duration = Math.max((long) ( + (float) HIDE_ANIM_DURATION + * (translationY - mButtonBarContainer.getTranslationY()) + / mButtonBarContainer.getHeight()), 0); + generateButtonBarAnimator( + mButtonBarContainer.getTranslationY(), translationY, + mButtonBarFloatingHeight, 0, duration); + } else { + mButtonBarContainer.setTranslationY(translationY); + mButtonBarContainer.setTranslationZ(0); + } + } + } else { + // not currently animating, have already hidden, snap to the right offset + mButtonBarContainer.setTranslationY(translationY); + mButtonBarContainer.setTranslationZ(0); + } + + mHiddenBefore = true; + } + + private void generateButtonBarAnimator( + float startY, float endY, float startZ, float endZ, long duration) { + mButtonBarAnimator = + ObjectAnimator.ofPropertyValuesHolder( + mButtonBarContainer, + PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, startY, endY), + PropertyValuesHolder.ofFloat(View.TRANSLATION_Z, startZ, endZ)); + mCurrentTranslation = endY; + mButtonBarAnimator.setDuration(duration); + mButtonBarAnimator.setInterpolator(mInterpolator); + mButtonBarAnimator.start(); + } } |