|
50 | 50 | import android.view.KeyEvent; |
51 | 51 | import android.view.LayoutInflater; |
52 | 52 | import android.view.MotionEvent; |
53 | | -import android.view.Surface; |
54 | 53 | import android.view.VelocityTracker; |
55 | 54 | import android.view.View; |
56 | 55 | import android.view.ViewGroup; |
@@ -213,6 +212,8 @@ public class PhoneStatusBar extends StatusBar { |
213 | 212 | boolean mAnimatingReveal = false; |
214 | 213 | int mViewDelta; |
215 | 214 | int[] mAbsPos = new int[2]; |
| 215 | + Runnable mPostCollapseCleanup = null; |
| 216 | + |
216 | 217 |
|
217 | 218 | // for disabling the status bar |
218 | 219 | int mDisabled = 0; |
@@ -1238,6 +1239,10 @@ void performCollapse() { |
1238 | 1239 | return; |
1239 | 1240 | } |
1240 | 1241 | mExpanded = false; |
| 1242 | + if (mPostCollapseCleanup != null) { |
| 1243 | + mPostCollapseCleanup.run(); |
| 1244 | + mPostCollapseCleanup = null; |
| 1245 | + } |
1241 | 1246 | } |
1242 | 1247 |
|
1243 | 1248 | void doAnimation() { |
@@ -2066,49 +2071,67 @@ final int mini(int a, int b) { |
2066 | 2071 | } |
2067 | 2072 | public void onClick(View v) { |
2068 | 2073 | synchronized (mNotificationData) { |
2069 | | - // let's also queue up 400ms worth of animated dismissals |
2070 | | - final int N = mini(5, mPile.getChildCount()); |
| 2074 | + // animate-swipe all dismissable notifications, then animate the shade closed |
| 2075 | + int numChildren = mPile.getChildCount(); |
2071 | 2076 |
|
2072 | | - final ArrayList<View> snapshot = new ArrayList<View>(N); |
2073 | | - for (int i=0; i<N; i++) { |
| 2077 | + int scrollTop = mScrollView.getScrollY(); |
| 2078 | + int scrollBottom = scrollTop + mScrollView.getHeight(); |
| 2079 | + final ArrayList<View> snapshot = new ArrayList<View>(numChildren); |
| 2080 | + for (int i=0; i<numChildren; i++) { |
2074 | 2081 | final View child = mPile.getChildAt(i); |
2075 | | - if (mPile.canChildBeDismissed(child)) snapshot.add(child); |
| 2082 | + if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop && |
| 2083 | + child.getTop() < scrollBottom) { |
| 2084 | + snapshot.add(child); |
| 2085 | + } |
2076 | 2086 | } |
| 2087 | + final int N = snapshot.size(); |
2077 | 2088 | new Thread(new Runnable() { |
2078 | 2089 | @Override |
2079 | 2090 | public void run() { |
2080 | | - final int ROW_DELAY = 100; |
2081 | | - |
2082 | | - mHandler.postDelayed(new Runnable() { |
2083 | | - public void run() { |
2084 | | - animateCollapse(false, 0f); |
2085 | | - } |
2086 | | - }, (N-1) * ROW_DELAY); |
2087 | | - |
2088 | | - mHandler.postDelayed(new Runnable() { |
| 2091 | + // Decrease the delay for every row we animate to give the sense of |
| 2092 | + // accelerating the swipes |
| 2093 | + final int ROW_DELAY_DECREMENT = 10; |
| 2094 | + int currentDelay = 140; |
| 2095 | + int totalDelay = 0; |
| 2096 | + |
| 2097 | + // Set the shade-animating state to avoid doing other work during |
| 2098 | + // all of these animations. In particular, avoid layout and |
| 2099 | + // redrawing when collapsing the shade. |
| 2100 | + mPile.setViewRemoval(false); |
| 2101 | + |
| 2102 | + mPostCollapseCleanup = new Runnable() { |
2089 | 2103 | public void run() { |
2090 | 2104 | try { |
| 2105 | + mPile.setViewRemoval(true); |
2091 | 2106 | mBarService.onClearAllNotifications(); |
2092 | | - } catch (RemoteException ex) { } |
| 2107 | + } catch (Exception ex) { } |
2093 | 2108 | } |
2094 | | - }, N * ROW_DELAY + 500); |
2095 | | - |
2096 | | - mPile.setAnimateBounds(false); // temporarily disable some re-layouts |
| 2109 | + }; |
2097 | 2110 |
|
| 2111 | + View sampleView = snapshot.get(0); |
| 2112 | + int width = sampleView.getWidth(); |
| 2113 | + final int velocity = (int)(width * 8); // 1000/8 = 125 ms duration |
2098 | 2114 | for (View v : snapshot) { |
2099 | 2115 | final View _v = v; |
2100 | | - mHandler.post(new Runnable() { |
| 2116 | + mHandler.postDelayed(new Runnable() { |
2101 | 2117 | @Override |
2102 | 2118 | public void run() { |
2103 | | - mPile.dismissRowAnimated(_v, (int)(ROW_DELAY*0.25f)); |
| 2119 | + mPile.dismissRowAnimated(_v, velocity); |
2104 | 2120 | } |
2105 | | - }); |
2106 | | - try { |
2107 | | - Thread.sleep(ROW_DELAY); |
2108 | | - } catch (InterruptedException ex) { } |
| 2121 | + }, totalDelay); |
| 2122 | + currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT); |
| 2123 | + totalDelay += currentDelay; |
2109 | 2124 | } |
2110 | | - |
2111 | | - mPile.setAnimateBounds(true); // reenable layout animation |
| 2125 | + // Delay the collapse animation until after all swipe animations have |
| 2126 | + // finished. Provide some buffer because there may be some extra delay |
| 2127 | + // before actually starting each swipe animation. Ideally, we'd |
| 2128 | + // synchronize the end of those animations with the start of the collaps |
| 2129 | + // exactly. |
| 2130 | + mHandler.postDelayed(new Runnable() { |
| 2131 | + public void run() { |
| 2132 | + animateCollapse(false); |
| 2133 | + } |
| 2134 | + }, totalDelay + 225); |
2112 | 2135 | } |
2113 | 2136 | }).start(); |
2114 | 2137 | } |
|
0 commit comments