diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 26152cdac136d..8df2c28060fbb 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -32,7 +32,6 @@
>
-
+ android:padding="12dp" />
+
@@ -116,7 +116,6 @@
android:id="@+id/date_time_group"
android:layout_width="wrap_content"
android:layout_height="19dp"
- android:layout_marginTop="4dp"
android:orientation="horizontal">
26dp
14sp16sp
+ 120dp12dp24dp12sp
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index f208470a2927c..d0f7e6eb805ab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -17,12 +17,10 @@
package com.android.systemui.qs;
import android.content.Context;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Space;
import com.android.systemui.R;
@@ -103,7 +101,7 @@ public class QuickQSPanel extends QSPanel {
private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
- private final ImageView mDownArrow;
+ private final Space mEndSpacer;
public HeaderTileLayout(Context context) {
super(context);
@@ -112,16 +110,10 @@ public class QuickQSPanel extends QSPanel {
setGravity(Gravity.CENTER_VERTICAL);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- int padding =
- mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding);
- mDownArrow = new ImageView(context);
- mDownArrow.setImageResource(R.drawable.ic_expand_more);
- mDownArrow.setImageTintList(ColorStateList.valueOf(context.getResources().getColor(
- android.R.color.white, null)));
- mDownArrow.setLayoutParams(generateLayoutParams());
- mDownArrow.setPadding(padding, padding, padding, padding);
+ mEndSpacer = new Space(context);
+ mEndSpacer.setLayoutParams(generateLayoutParams());
updateDownArrowMargin();
- addView(mDownArrow);
+ addView(mEndSpacer);
setOrientation(LinearLayout.HORIZONTAL);
}
@@ -132,10 +124,10 @@ public class QuickQSPanel extends QSPanel {
}
private void updateDownArrowMargin() {
- LayoutParams params = (LayoutParams) mDownArrow.getLayoutParams();
+ LayoutParams params = (LayoutParams) mEndSpacer.getLayoutParams();
params.setMarginStart(mContext.getResources().getDimensionPixelSize(
R.dimen.qs_expand_margin));
- mDownArrow.setLayoutParams(params);
+ mEndSpacer.setLayoutParams(params);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
new file mode 100644
index 0000000000000..5e6b52b3b1af3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
@@ -0,0 +1,241 @@
+/*
+ * 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.animation.Keyframe;
+import android.util.MathUtils;
+import android.util.Property;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class, that handles similar properties as animators (delay, interpolators)
+ * but can have a float input as to the amount they should be in effect. This allows
+ * easier animation that tracks input.
+ *
+ * All "delays" and "times" are as fractions from 0-1.
+ */
+public class TouchAnimator {
+
+ private final Object[] mTargets;
+ private final Property[] mProperties;
+ private final KeyframeSet[] mKeyframeSets;
+ private final float mStartDelay;
+ private final float mEndDelay;
+ private final float mSpan;
+ private final Interpolator mInterpolator;
+ private final Listener mListener;
+ private float mLastT;
+
+ private TouchAnimator(Object[] targets, Property[] properties, KeyframeSet[] keyframeSets,
+ float startDelay, float endDelay, Interpolator interpolator, Listener listener) {
+ mTargets = targets;
+ mProperties = properties;
+ mKeyframeSets = keyframeSets;
+ mStartDelay = startDelay;
+ mEndDelay = endDelay;
+ mSpan = (1 - mEndDelay - mStartDelay);
+ mInterpolator = interpolator;
+ mListener = listener;
+ }
+
+ public void setPosition(float fraction) {
+ float t = MathUtils.constrain((fraction - mStartDelay) / mSpan, 0, 1);
+ if (mInterpolator != null) {
+ t = mInterpolator.getInterpolation(t);
+ }
+ if (mListener != null) {
+ if (mLastT == 0 || mLastT == 1) {
+ if (t != 0) {
+ mListener.onAnimationStarted();
+ }
+ } else if (t == 1) {
+ mListener.onAnimationAtEnd();
+ } else if (t == 0) {
+ mListener.onAnimationAtStart();
+ }
+ mLastT = t;
+ }
+ for (int i = 0; i < mTargets.length; i++) {
+ Object value = mKeyframeSets[i].getValue(t);
+ mProperties[i].set(mTargets[i], value);
+ }
+ }
+
+ public static class ListenerAdapter implements Listener {
+ @Override
+ public void onAnimationAtStart() { }
+
+ @Override
+ public void onAnimationAtEnd() { }
+
+ @Override
+ public void onAnimationStarted() { }
+ }
+
+ public interface Listener {
+ /**
+ * Called when the animator moves into a position of "0". Start and end delays are
+ * taken into account, so this position may cover a range of fractional inputs.
+ */
+ void onAnimationAtStart();
+
+ /**
+ * Called when the animator moves into a position of "0". Start and end delays are
+ * taken into account, so this position may cover a range of fractional inputs.
+ */
+ void onAnimationAtEnd();
+
+ /**
+ * Called when the animator moves out of the start or end position and is in a transient
+ * state.
+ */
+ void onAnimationStarted();
+ }
+
+ public static class Builder {
+ private List