diff options
| author | 2016-02-20 16:53:02 +0000 | |
|---|---|---|
| committer | 2016-02-20 16:53:04 +0000 | |
| commit | 865a4ee0cddedc8ef11f8370390e197e9ae95067 (patch) | |
| tree | 717b4573e1369f108463173c0f0a2beff33539ff | |
| parent | 0cbfdd3a201f6565a54aa87c3de09955e328c451 (diff) | |
| parent | 8d1253e944f47db05a4400793774e7871a28dd73 (diff) | |
Merge changes Icb8e2097,I9a2a16f9 into nyc-dev
* changes:
Optimization for TouchAnimator
QS Animations - first pass, still not spec
14 files changed, 354 insertions, 80 deletions
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml index eef08baed736..a246e0dffdd9 100644 --- a/packages/SystemUI/res/layout/qs_paged_page.xml +++ b/packages/SystemUI/res/layout/qs_paged_page.xml @@ -19,4 +19,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tile_page" android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" /> diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml index c23c745931c6..c80d31d1100e 100644 --- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml +++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml @@ -18,7 +18,9 @@ <com.android.systemui.qs.PagedTileLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false"> <FrameLayout android:id="@+id/page_decor" diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml index 9f90af231b20..b8f10dbec87c 100644 --- a/packages/SystemUI/res/layout/qs_panel.xml +++ b/packages/SystemUI/res/layout/qs_panel.xml @@ -26,7 +26,9 @@ android:layout_marginTop="@dimen/status_bar_header_height" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingBottom="8dp" /> + android:paddingBottom="8dp" + android:clipToPadding="false" + android:clipChildren="false" /> <include layout="@layout/quick_status_bar_expanded_header" /> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 96783ab3e7b6..ee61e00225a6 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -178,7 +178,7 @@ <dimen name="qs_date_alarm_anim_translation">26dp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> - <dimen name="qs_header_gear_translation">120dp</dimen> + <dimen name="qs_header_gear_translation">150dp</dimen> <dimen name="qs_page_indicator_size">12dp</dimen> <dimen name="qs_tile_icon_size">24dp</dimen> <dimen name="qs_tile_text_size">12sp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 8e9857d27f74..0915ee1c1745 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -27,6 +27,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { private int mNumPages; private View mDecorGroup; + private PageListener mPageListener; public PagedTileLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -36,10 +37,14 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { public void onPageSelected(int position) { if (mPageIndicator == null) return; mPageIndicator.setLocation(position); + if (mPageListener != null) { + mPageListener.onPageChanged(position); + } } @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + public void onPageScrolled(int position, float positionOffset, + int positionOffsetPixels) { if (mPageIndicator == null) return; mPageIndicator.setLocation(position + positionOffset); } @@ -80,6 +85,10 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { } } + public void setPageListener(PageListener listener) { + mPageListener = listener; + } + private void postDistributeTiles() { removeCallbacks(mDistribute); post(mDistribute); @@ -198,4 +207,8 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { return view == object; } }; + + public interface PageListener { + void onPageChanged(int page); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java new file mode 100644 index 000000000000..6479b0ce6833 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs; + +import android.util.Log; +import android.view.View; +import android.view.View.OnLayoutChangeListener; +import android.view.ViewGroup; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.PathInterpolator; +import android.widget.TextView; +import com.android.systemui.Interpolators; +import com.android.systemui.qs.PagedTileLayout.PageListener; +import com.android.systemui.qs.QSPanel.QSTileLayout; +import com.android.systemui.qs.QSTile.Host.Callback; +import com.android.systemui.qs.TouchAnimator.Builder; +import com.android.systemui.qs.TouchAnimator.Listener; +import com.android.systemui.statusbar.phone.QSTileHost; + +import java.util.ArrayList; +import java.util.Collection; + +public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener { + + private static final String TAG = "QSAnimator"; + + public static final PathInterpolator TRANSLATION_Y_INTERPOLATOR = + new PathInterpolator(.1f, .3f, 1, 1); + + public static final float EXPANDED_TILE_DELAY = .7f; + + private final ArrayList<View> mAllViews = new ArrayList<>(); + private final QuickQSPanel mQuickQsPanel; + private final QSPanel mQsPanel; + private final QSContainer mQsContainer; + + private boolean mOnFirstPage = true; + private TouchAnimator mFirstPageAnimator; + private TouchAnimator mFirstPageDelayedAnimator; + private TouchAnimator mTranslationYAnimator; + private TouchAnimator mNonfirstPageAnimator; + + public QSAnimator(QSContainer container, QuickQSPanel quickPanel, QSPanel panel) { + mQsContainer = container; + mQuickQsPanel = quickPanel; + mQsPanel = panel; + mQuickQsPanel.addOnLayoutChangeListener(this); + mQsPanel.addOnLayoutChangeListener(this); + QSTileLayout tileLayout = mQsPanel.getTileLayout(); + if (tileLayout instanceof PagedTileLayout) { + ((PagedTileLayout) tileLayout).setPageListener(this); + } else { + Log.w(TAG, "QS Not using page layout"); + } + } + + public void setHost(QSTileHost qsh) { + qsh.addCallback(this); + } + + @Override + public void onPageChanged(int page) { + mOnFirstPage = page == 0; + if (!mOnFirstPage) { + clearAnimationState(); + } + } + + private void updateAnimators() { + TouchAnimator.Builder firstPageBuilder = new Builder(); + TouchAnimator.Builder translationYBuilder = new Builder(); + TouchAnimator.Builder firstPageDelayedBuilder = new Builder(); + Collection<QSTile<?>> tiles = mQsPanel.getHost().getTiles(); + int count = 0; + int[] loc1 = new int[2]; + int[] loc2 = new int[2]; + firstPageDelayedBuilder.setStartDelay(EXPANDED_TILE_DELAY); + firstPageBuilder.setListener(this); + translationYBuilder.setInterpolator(TRANSLATION_Y_INTERPOLATOR); + mAllViews.clear(); + for (QSTile<?> tile : tiles) { + QSTileBaseView tileView = mQsPanel.getTileView(tile); + final TextView label = ((QSTileView) tileView).getLabel(); + if (count++ < 5) { + // Quick tiles. + QSTileBaseView quickTileView = mQuickQsPanel.getTileView(tile); + final View tileIcon = tileView.getIcon(); + + getRelativePosition(loc1, quickTileView.getIcon(), mQsContainer); + getRelativePosition(loc2, tileIcon, mQsContainer); + final int xDiff = loc2[0] - loc1[0]; + final int yDiff = loc2[1] - loc1[1]; + // Move the quick tile right from its location to the new one. + firstPageBuilder.addFloat(quickTileView, "translationX", 0, xDiff); + translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); + + // Counteract the parent translation on the tile. So we have a static base to + // animate off from. + firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0); + + // Move the real tile's icon and label from the quick tile position to its final + // location. + firstPageBuilder.addFloat(tileIcon, "translationX", -xDiff, 0); + translationYBuilder.addFloat(tileIcon, "translationY", -yDiff, 0); + firstPageBuilder.addFloat(label, "translationX", -xDiff, 0); + translationYBuilder.addFloat(label, "translationY", -yDiff, 0); + + // Fade in the label as we reach the final position. + firstPageDelayedBuilder.addFloat(label, "alpha", 0, 1); + mAllViews.add(quickTileView); + } else { + firstPageDelayedBuilder.addFloat(tileView, "alpha", 0, 1); + } + mAllViews.add(tileView); + mAllViews.add(label); + } + mFirstPageAnimator = firstPageBuilder.build(); + mFirstPageDelayedAnimator = firstPageDelayedBuilder.build(); + mTranslationYAnimator = translationYBuilder.build(); + mNonfirstPageAnimator = new TouchAnimator.Builder() + .addFloat(mQuickQsPanel, "alpha", 1, 0) + .setEndDelay(.5f) + .build(); + } + + private void getRelativePosition(int[] loc1, View view, View parent) { + loc1[0] = 0 + view.getWidth() / 2; + loc1[1] = 0; + getRelativePositionInt(loc1, view, parent); + } + + private void getRelativePositionInt(int[] loc1, View view, View parent) { + if(view == parent || view == null) return; + loc1[0] += view.getLeft(); + loc1[1] += view.getTop(); + getRelativePositionInt(loc1, (View) view.getParent(), parent); + } + + public void setPosition(float position) { + if (mFirstPageAnimator == null) return; + if (mOnFirstPage) { + mQuickQsPanel.setAlpha(1); + mFirstPageAnimator.setPosition(position); + mFirstPageDelayedAnimator.setPosition(position); + mTranslationYAnimator.setPosition(position); + } else { + mNonfirstPageAnimator.setPosition(position); + } + } + + @Override + public void onAnimationAtStart() { + + } + + @Override + public void onAnimationAtEnd() { + mQuickQsPanel.setVisibility(View.INVISIBLE); + } + + @Override + public void onAnimationStarted() { + mQuickQsPanel.setVisibility(View.VISIBLE); + } + + private void clearAnimationState() { + final int N = mAllViews.size(); + mQuickQsPanel.setAlpha(0); + for (int i = 0; i < N; i++) { + View v = mAllViews.get(i); + v.setAlpha(1); + v.setTranslationX(1); + v.setTranslationY(1); + } + } + + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, + int oldTop, int oldRight, int oldBottom) { + updateAnimators(); + } + + @Override + public void onTilesChanged() { + // Give the QS panels a moment to generate their new tiles, then create all new animators + // hooked up to the new views. + mQsPanel.post(mUpdateAnimators); + } + + private Runnable mUpdateAnimators = new Runnable() { + @Override + public void run() { + updateAnimators(); + } + }; +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java index 58c3b7eb44af..c59da8d8baf7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java @@ -27,6 +27,7 @@ import android.widget.FrameLayout; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.phone.BaseStatusBarHeader; +import com.android.systemui.statusbar.phone.QSTileHost; import com.android.systemui.statusbar.stack.StackStateAnimator; /** @@ -49,6 +50,7 @@ public class QSContainer extends FrameLayout { private boolean mStackScrollerOverscrolling; private long mDelay; + private QSAnimator mQSAnimator; public QSContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -61,6 +63,15 @@ public class QSContainer extends FrameLayout { mQSDetail = (QSDetail) findViewById(R.id.qs_detail); mQSDetail.setQsPanel(mQSPanel); mHeader = (BaseStatusBarHeader) findViewById(R.id.header); + mQSAnimator = new QSAnimator(this, (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel), + mQSPanel); + } + + public void setHost(QSTileHost qsh) { + mQSPanel.setHost(qsh); + mHeader.setQSPanel(mQSPanel); + mQSDetail.setHost(qsh); + mQSAnimator.setHost(qsh); } @Override @@ -171,6 +182,7 @@ public class QSContainer extends FrameLayout { mHeader.setExpansion(mKeyguardShowing ? 1 : expansion); mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight()); mQSDetail.setFullyExpanded(expansion == 1); + mQSAnimator.setPosition(expansion); updateBottom(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 5e653dd5e879..30a985052bc2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -25,7 +25,6 @@ import android.os.Message; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import com.android.internal.logging.MetricsLogger; @@ -45,7 +44,7 @@ import java.util.ArrayList; import java.util.Collection; /** View that represents the quick settings tile panel. **/ -public class QSPanel extends FrameLayout implements Tunable { +public class QSPanel extends LinearLayout implements Tunable { public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness"; @@ -66,7 +65,6 @@ public class QSPanel extends FrameLayout implements Tunable { protected QSFooter mFooter; private boolean mGridContentVisible = true; - protected LinearLayout mQsContainer; protected QSTileLayout mTileLayout; private QSCustomizer mCustomizePanel; @@ -80,20 +78,15 @@ public class QSPanel extends FrameLayout implements Tunable { super(context, attrs); mContext = context; - - mQsContainer = new LinearLayout(mContext); - mQsContainer.setOrientation(LinearLayout.VERTICAL); - mQsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.WRAP_CONTENT)); - addView(mQsContainer); + setOrientation(VERTICAL); mBrightnessView = LayoutInflater.from(context).inflate( R.layout.quick_settings_brightness_dialog, this, false); - mQsContainer.addView(mBrightnessView); + addView(mBrightnessView); mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate( - R.layout.qs_paged_tile_layout, mQsContainer, false); - mQsContainer.addView((View) mTileLayout); + R.layout.qs_paged_tile_layout, this, false); + addView((View) mTileLayout); findViewById(android.R.id.edit).setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { @@ -107,7 +100,7 @@ public class QSPanel extends FrameLayout implements Tunable { }); mFooter = new QSFooter(this, context); - mQsContainer.addView(mFooter.getView()); + addView(mFooter.getView()); updateResources(); @@ -187,7 +180,7 @@ public class QSPanel extends FrameLayout implements Tunable { final Resources res = mContext.getResources(); mPanelPaddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom); mBrightnessPaddingTop = res.getDimensionPixelSize(R.dimen.qs_brightness_padding_top); - mQsContainer.setPadding(0, mBrightnessPaddingTop, 0, mPanelPaddingBottom); + setPadding(0, mBrightnessPaddingTop, 0, mPanelPaddingBottom); for (TileRecord r : mRecords) { r.tile.clearState(); } @@ -214,6 +207,9 @@ public class QSPanel extends FrameLayout implements Tunable { public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; + if (!mExpanded && mTileLayout instanceof PagedTileLayout) { + ((PagedTileLayout) mTileLayout).setCurrentItem(0, false); + } MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, mExpanded); if (!mExpanded) { closeDetail(); @@ -377,7 +373,7 @@ public class QSPanel extends FrameLayout implements Tunable { } public int getGridHeight() { - return mQsContainer.getMeasuredHeight(); + return getMeasuredHeight(); } protected void handleShowDetail(Record r, boolean show) { @@ -426,7 +422,7 @@ public class QSPanel extends FrameLayout implements Tunable { void setGridContentVisibility(boolean visible) { int newVis = visible ? VISIBLE : INVISIBLE; - mQsContainer.setVisibility(newVis); + setVisibility(newVis); if (mGridContentVisible != visible) { MetricsLogger.visibility(mContext, MetricsEvent.QS_PANEL, newVis); } @@ -469,6 +465,19 @@ public class QSPanel extends FrameLayout implements Tunable { } } + QSTileLayout getTileLayout() { + return mTileLayout; + } + + QSTileBaseView getTileView(QSTile<?> tile) { + for (TileRecord r : mRecords) { + if (r.tile == tile) { + return r.tileView; + } + } + return null; + } + private class H extends Handler { private static final int SHOW_DETAIL = 1; private static final int SET_TILE_VISIBILITY = 2; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java index f74117c78671..f35aacf8f72d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java @@ -49,6 +49,8 @@ public class QSTileBaseView extends LinearLayout { // Default to Quick Tile padding, and QSTileView will specify its own padding. int padding = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding); setPadding(padding, padding, padding, padding); + setClipChildren(false); + setClipToPadding(false); } private Drawable newTileBackground() { @@ -111,6 +113,10 @@ public class QSTileBaseView extends LinearLayout { setContentDescription(state.contentDescription); } + View getIcon() { + return mIcon; + } + private class H extends Handler { private static final int STATE_CHANGED = 1; public H() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java index 523792b3c263..6fa23e794041 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java @@ -57,6 +57,10 @@ public class QSTileView extends QSTileBaseView { setGravity(Gravity.CENTER); } + TextView getLabel() { + return mLabel; + } + private void updateTopPadding() { Resources res = getResources(); int padding = res.getDimensionPixelSize(R.dimen.qs_tile_padding_top); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index d0f7e6eb805a..abe4c7798a01 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -43,10 +43,10 @@ public class QuickQSPanel extends QSPanel { for (int i = 0; i < mRecords.size(); i++) { mTileLayout.removeTile(mRecords.get(i)); } - mQsContainer.removeView((View) mTileLayout); + removeView((View) mTileLayout); } mTileLayout = new HeaderTileLayout(context); - mQsContainer.addView((View) mTileLayout, 1 /* Between brightness and footer */); + addView((View) mTileLayout, 1 /* Between brightness and footer */); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java index 5e6b52b3b1af..b33d31df1cbd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java @@ -15,8 +15,10 @@ package com.android.systemui.qs; import android.animation.Keyframe; +import android.util.Log; import android.util.MathUtils; import android.util.Property; +import android.view.View; import android.view.animation.Interpolator; import java.util.ArrayList; @@ -129,11 +131,36 @@ public class TouchAnimator { private void add(Object target, String property, KeyframeSet keyframeSet) { mTargets.add(target); - // TODO: Optimize the properties here, to use those in View when possible. - mProperties.add(Property.of(target.getClass(), float.class, property)); + mProperties.add(getProperty(target, property)); mValues.add(keyframeSet); } + private static Property getProperty(Object target, String property) { + if (target instanceof View) { + switch (property) { + case "translationX": + return View.TRANSLATION_X; + case "translationY": + return View.TRANSLATION_Y; + case "translationZ": + return View.TRANSLATION_Z; + case "alpha": + return View.ALPHA; + case "rotation": + return View.ROTATION; + case "x": + return View.X; + case "y": + return View.Y; + case "scaleX": + return View.SCALE_X; + case "scaleY": + return View.SCALE_Y; + } + } + return Property.of(target.getClass(), float.class, property); + } + public Builder setStartDelay(float startDelay) { mStartDelay = startDelay; return this; @@ -164,77 +191,61 @@ public class TouchAnimator { private static abstract class KeyframeSet { - private final Keyframe[] mKeyframes; + private final float mFrameWidth; + private final int mSize; - public KeyframeSet(Keyframe[] keyframes) { - mKeyframes = keyframes; + public KeyframeSet(int size) { + mSize = size; + mFrameWidth = 1 / (float) (size - 1); } Object getValue(float fraction) { int i; - for (i = 1; i < mKeyframes.length && fraction > mKeyframes[i].getFraction(); i++) ; - Keyframe first = mKeyframes[i - 1]; - Keyframe second = mKeyframes[i]; - float amount = (fraction - first.getFraction()) - / (second.getFraction() - first.getFraction()); - return interpolate(first, second, amount); + for (i = 1; i < mSize - 1 && fraction > mFrameWidth; i++); + float amount = fraction / mFrameWidth; + return interpolate(i, amount); } - protected abstract Object interpolate(Keyframe first, Keyframe second, float amount); + protected abstract Object interpolate(int index, float amount); public static KeyframeSet ofInt(int... values) { - int numKeyframes = values.length; - Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes, 2)]; - if (numKeyframes == 1) { - keyframes[0] = Keyframe.ofInt(0f); - keyframes[1] = Keyframe.ofInt(1f, values[0]); - } else { - keyframes[0] = Keyframe.ofInt(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]); - } - } - return new IntKeyframeSet(keyframes); + return new IntKeyframeSet(values); } public static KeyframeSet ofFloat(float... values) { - int numKeyframes = values.length; - Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes, 2)]; - if (numKeyframes == 1) { - keyframes[0] = Keyframe.ofFloat(0f); - keyframes[1] = Keyframe.ofFloat(1f, values[0]); - } else { - keyframes[0] = Keyframe.ofFloat(0f, values[0]); - for (int i = 1; i < numKeyframes; ++i) { - keyframes[i] = Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]); - } - } - return new FloatKeyframeSet(keyframes); + return new FloatKeyframeSet(values); } } - public static class FloatKeyframeSet extends KeyframeSet { - public FloatKeyframeSet(Keyframe[] keyframes) { - super(keyframes); + private static class FloatKeyframeSet extends KeyframeSet { + private final float[] mValues; + + public FloatKeyframeSet(float[] values) { + super(values.length); + mValues = values; } @Override - protected Object interpolate(Keyframe first, Keyframe second, float amount) { - float firstFloat = (float) first.getValue(); - float secondFloat = (float) second.getValue(); + protected Object interpolate(int index, float amount) { + float firstFloat = mValues[index - 1]; + float secondFloat = mValues[index]; return firstFloat + (secondFloat - firstFloat) * amount; } } - public static class IntKeyframeSet extends KeyframeSet { - public IntKeyframeSet(Keyframe[] keyframes) { - super(keyframes); + private static class IntKeyframeSet extends KeyframeSet { + + private final int[] mValues; + + public IntKeyframeSet(int[] values) { + super(values.length); + mValues = values; } @Override - protected Object interpolate(Keyframe first, Keyframe second, float amount) { - int firstFloat = (int) first.getValue(); - int secondFloat = (int) second.getValue(); + protected Object interpolate(int index, float amount) { + int firstFloat = mValues[index - 1]; + int secondFloat = mValues[index]; return (int) (firstFloat + (secondFloat - firstFloat) * amount); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 032957f50ff4..1089852191fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -116,7 +116,7 @@ import com.android.systemui.classifier.FalsingManager; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; -import com.android.systemui.qs.QSDetail; +import com.android.systemui.qs.QSContainer; import com.android.systemui.qs.QSPanel; import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.recents.events.EventBus; @@ -872,13 +872,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mCastController, mFlashlightController, mUserSwitcherController, mUserInfoController, mKeyguardMonitor, mSecurityController, mBatteryController, mIconController); - mQSPanel.setHost(qsh); mQSPanel.setTiles(qsh.getTiles()); mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow); mQSPanel.setBrightnessMirror(mBrightnessMirrorController); - mHeader.setQSPanel(mQSPanel); - QSDetail qsDetail = (QSDetail) mStatusBarWindow.findViewById(R.id.qs_detail); - qsDetail.setHost(qsh); + QSContainer qsContainer = (QSContainer) mStatusBarWindow.findViewById( + R.id.quick_settings_container); + qsContainer.setHost(qsh); qsh.addCallback(new QSTileHost.Callback() { @Override public void onTilesChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index bd5bac2506fb..ab8067ddebbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -34,6 +34,7 @@ import android.widget.Toast; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; +import com.android.systemui.qs.QSAnimator; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.QuickQSPanel; @@ -50,7 +51,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements private static final String TAG = "QuickStatusBarHeader"; - private static final float EXPAND_INDICATOR_THRESHOLD = .8f; + private static final float EXPAND_INDICATOR_THRESHOLD = .93f; private ActivityStarter mActivityStarter; private NextAlarmController mNextAlarmController; @@ -89,6 +90,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements private TouchAnimator mFirstHalfAnimator; private TouchAnimator mDateSizeAnimator; private TouchAnimator mAlarmTranslation; + private TouchAnimator mSettingsAlpha; private float mExpansionAmount; public QuickStatusBarHeader(Context context, AttributeSet attrs) { @@ -164,18 +166,16 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mAnimator = new TouchAnimator.Builder() .addFloat(mSettingsContainer, "translationY", -mGearTranslation, 0) .addFloat(mMultiUserSwitch, "translationY", -mGearTranslation, 0) - .addFloat(mSettingsButton, "rotation", -90, 0) .setListener(this) .build(); mSecondHalfAnimator = new TouchAnimator.Builder() - .addFloat(mSettingsButton, "rotation", -90, 0) + .addFloat(mSettingsButton, "rotation", -180, 0) .addFloat(mAlarmStatus, "alpha", 0, 1) .addFloat(mEmergencyOnly, "alpha", 0, 1) .setStartDelay(.5f) .build(); mFirstHalfAnimator = new TouchAnimator.Builder() .addFloat(mAlarmStatusCollapsed, "alpha", 1, 0) - .addFloat(mHeaderQsPanel, "alpha", 1, 0) .setEndDelay(.5f) .build(); mDateSizeAnimator = new TouchAnimator.Builder() @@ -183,6 +183,11 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements .addFloat(mDateTimeGroup, "scaleY", 1, mDateScaleFactor) .setStartDelay(.36f) .build(); + mSettingsAlpha = new TouchAnimator.Builder() + .addFloat(mSettingsContainer, "alpha", 0, 1) + .addFloat(mMultiUserSwitch, "alpha", 0, 1) + .setStartDelay(QSAnimator.EXPANDED_TILE_DELAY) + .build(); } @Override @@ -221,6 +226,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mFirstHalfAnimator.setPosition(headerExpansionFraction); mDateSizeAnimator.setPosition(headerExpansionFraction); mAlarmTranslation.setPosition(headerExpansionFraction); + mSettingsAlpha.setPosition(headerExpansionFraction); updateAlarmVisibilities(); |