summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2015-06-17 12:45:16 -0400
committerJason Monk <jmonk@google.com>2015-06-18 13:26:27 -0400
commitbfaa53e0b09b255e1ba44017052041e435c6f5e0 (patch)
treef5dbd673d7491620a0e86a48fc4e484cdb794746 /src
parentd8cb9a81bbd71737149a3fe3fba8bb13c05439c3 (diff)
downloadandroid_packages_apps_PackageInstaller-bfaa53e0b09b255e1ba44017052041e435c6f5e0.tar.gz
android_packages_apps_PackageInstaller-bfaa53e0b09b255e1ba44017052041e435c6f5e0.tar.bz2
android_packages_apps_PackageInstaller-bfaa53e0b09b255e1ba44017052041e435c6f5e0.zip
Fix animating between very different heights
- Expand ViewHeightController so it can expand up or down - Control the height of all containers in the hierarchy - Intercept touch events and compensate for any top offset on the root view, since we expand upwards - Remove the current description from the description container so that it can shrink in relayout if necessary. Bug: 21879037 Bug: 21784297 Change-Id: I3ad562158013b75c5e9150cbd91c96c6ff4941c9
Diffstat (limited to 'src')
-rw-r--r--src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java12
-rw-r--r--src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java89
-rw-r--r--src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java3
3 files changed, 82 insertions, 22 deletions
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
index ba2a4cd9..98773f54 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java
@@ -37,6 +37,8 @@ import android.text.style.ForegroundColorSpan;
import android.util.ArrayMap;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@@ -146,6 +148,16 @@ public class GrantPermissionsActivity extends Activity
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ View rootView = getWindow().getDecorView();
+ if (rootView.getTop() != 0) {
+ // We are animating the top view, need to compensate for that in motion events.
+ ev.setLocation(ev.getX(), ev.getY() - rootView.getTop());
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mViewHandler.saveInstanceState(outState);
diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java
index d755feeb..1f95352d 100644
--- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java
+++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java
@@ -28,6 +28,8 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.ViewRootImpl;
import android.view.WindowManager.LayoutParams;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -38,6 +40,8 @@ import android.widget.TextView;
import com.android.packageinstaller.R;
+import java.util.ArrayList;
+
final class GrantPermissionsDefaultViewHandler
implements GrantPermissionsViewHandler, OnClickListener {
@@ -76,7 +80,7 @@ final class GrantPermissionsDefaultViewHandler
private CheckBox mDoNotAskCheckbox;
private Button mAllowButton;
- private ViewHeightController mRootViewHeightController;
+ private ArrayList<ViewHeightController> mHeightControllers;
private ManualLayoutFrame mRootView;
// Needed for animation
@@ -144,18 +148,29 @@ final class GrantPermissionsDefaultViewHandler
updateGroup();
}
}
-
updateDoNotAskCheckBox();
+
}
private void animateToPermission() {
- if (mRootViewHeightController == null) {
- // Allow height control of the real root view, not the root of what we inflate.
- // Need to do it on the root view so that the background drawable of the dialog
- // moves with the animation.
- View realRootView = mRootView.getViewRootImpl().getView();
- mRootViewHeightController = new ViewHeightController(realRootView);
- mRootViewHeightController.setHeight(realRootView.getHeight());
+ if (mHeightControllers == null) {
+ // We need to manually control the height of any views heigher than the root that
+ // we inflate. Find all the views up to the root and create ViewHeightControllers for
+ // them.
+ mHeightControllers = new ArrayList<>();
+ ViewRootImpl viewRoot = mRootView.getViewRootImpl();
+ ViewParent v = mRootView.getParent();
+ addHeightController(mDialogContainer);
+ addHeightController(mRootView);
+ while (v != viewRoot) {
+ addHeightController((View) v);
+ v = v.getParent();
+ }
+ // On the heighest level view, we want to setTop rather than setBottom to control the
+ // height, this way the dialog will grow up rather than down.
+ ViewHeightController realRootView =
+ mHeightControllers.get(mHeightControllers.size() - 1);
+ realRootView.setControlTop(true);
}
// Grab the current height/y positions, then wait for the layout to change,
@@ -205,7 +220,14 @@ final class GrantPermissionsDefaultViewHandler
int width = mDescContainer.getRootView().getWidth();
mDescContainer.addView(mNextDesc);
mNextDesc.setTranslationX(width);
+
final View oldDesc = mCurrentDesc;
+ // Remove the old view from the description, so that we can shrink if necessary.
+ mDescContainer.removeView(oldDesc);
+ oldDesc.setPadding(mDescContainer.getLeft(), mDescContainer.getTop(),
+ mRootView.getRight() - mDescContainer.getRight(), 0);
+ mRootView.addView(oldDesc);
+
mCurrentDesc = mNextDesc;
mNextDesc.animate()
.translationX(0)
@@ -217,12 +239,18 @@ final class GrantPermissionsDefaultViewHandler
@Override
public void onAnimationEnd(Animator animation) {
// This is the longest animation, when it finishes, we are done.
- mDescContainer.removeView(oldDesc);
+ mRootView.removeView(oldDesc);
}
})
.start();
}
+ private void addHeightController(View v) {
+ ViewHeightController heightController = new ViewHeightController(v);
+ heightController.setHeight(v.getHeight());
+ mHeightControllers.add(heightController);
+ }
+
private SparseArray<Float> getViewPositions() {
SparseArray<Float> locMap = new SparseArray<>();
final int N = mDialogContainer.getChildCount();
@@ -254,7 +282,9 @@ final class GrantPermissionsDefaultViewHandler
.start();
}
}
- mRootViewHeightController.animateAddHeight(heightDiff);
+ for (int i = 0; i < mHeightControllers.size(); i++) {
+ mHeightControllers.get(i).animateAddHeight(heightDiff);
+ }
}
@Override
@@ -344,38 +374,53 @@ final class GrantPermissionsDefaultViewHandler
private static final class ViewHeightController implements OnLayoutChangeListener {
private final View mView;
private int mHeight;
+ private int mNextHeight;
+ private boolean mControlTop;
+ private ObjectAnimator mAnimator;
public ViewHeightController(View view) {
mView = view;
mView.addOnLayoutChangeListener(this);
}
+ public void setControlTop(boolean controlTop) {
+ mControlTop = controlTop;
+ }
+
public void animateAddHeight(int heightDiff) {
if (heightDiff != 0) {
- final int startHeight = mHeight;
- final int endHeight = startHeight + heightDiff;
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "height",
- startHeight, endHeight);
- animator.setStartDelay(SIZE_START_DELAY);
- animator.setDuration(SIZE_START_LENGTH);
- animator.start();
+ if (mNextHeight == 0) {
+ mNextHeight = mHeight;
+ }
+ mNextHeight += heightDiff;
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ mAnimator = ObjectAnimator.ofInt(this, "height", mHeight, mNextHeight);
+ mAnimator.setStartDelay(SIZE_START_DELAY);
+ mAnimator.setDuration(SIZE_START_LENGTH);
+ mAnimator.start();
}
}
public void setHeight(int height) {
mHeight = height;
- updateTop();
+ updateHeight();
}
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
// Ensure that the height never changes.
- updateTop();
+ updateHeight();
}
- private void updateTop() {
- mView.setTop(mView.getBottom() - mHeight);
+ private void updateHeight() {
+ if (mControlTop) {
+ mView.setTop(mView.getBottom() - mHeight);
+ } else {
+ mView.setBottom(mView.getTop() + mHeight);
+ }
}
}
}
diff --git a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java
index 97049df8..99a74e75 100644
--- a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java
+++ b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java
@@ -17,6 +17,7 @@ package com.android.packageinstaller.permission.ui;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.FrameLayout;
/**
@@ -30,6 +31,8 @@ public class ManualLayoutFrame extends FrameLayout {
private int mDesiredHeight;
private int mHeight;
+ private View mOffsetView;
+
public ManualLayoutFrame(Context context, AttributeSet attrs) {
super(context, attrs);
setClipChildren(false);