Loading packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml +5 −6 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,6 @@ > > <LinearLayout <LinearLayout android:id="@+id/expanded_group" android:layout_width="wrap_content" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_height="48dp" android:gravity="center" android:gravity="center" Loading Loading @@ -80,12 +79,12 @@ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> <ImageView <com.android.systemui.statusbar.phone.ExpandableIndicator android:id="@+id/expand_indicator" android:layout_width="48dp" android:layout_width="48dp" android:layout_height="48dp" android:layout_height="48dp" android:padding="12dp" android:padding="12dp" /> android:src="@drawable/ic_expand_less" android:tint="@android:color/white" /> </LinearLayout> </LinearLayout> <TextView <TextView Loading @@ -109,6 +108,7 @@ android:layout_height="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_alignParentTop="true" android:layout_marginTop="4dp" android:layout_marginStart="16dp" android:layout_marginStart="16dp" android:gravity="start" android:gravity="start" android:orientation="vertical"> android:orientation="vertical"> Loading @@ -116,7 +116,6 @@ android:id="@+id/date_time_group" android:id="@+id/date_time_group" android:layout_width="wrap_content" android:layout_width="wrap_content" android:layout_height="19dp" android:layout_height="19dp" android:layout_marginTop="4dp" android:orientation="horizontal"> android:orientation="horizontal"> <include layout="@layout/split_clock_view" <include layout="@layout/split_clock_view" Loading packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,7 @@ <dimen name="qs_date_alarm_anim_translation">26dp</dimen> <dimen name="qs_date_alarm_anim_translation">26dp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> <dimen name="qs_header_gear_translation">120dp</dimen> <dimen name="qs_page_indicator_size">12dp</dimen> <dimen name="qs_page_indicator_size">12dp</dimen> <dimen name="qs_tile_icon_size">24dp</dimen> <dimen name="qs_tile_icon_size">24dp</dimen> <dimen name="qs_tile_text_size">12sp</dimen> <dimen name="qs_tile_text_size">12sp</dimen> Loading packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +6 −14 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,10 @@ package com.android.systemui.qs; package com.android.systemui.qs; import android.content.Context; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Configuration; import android.util.AttributeSet; import android.util.AttributeSet; import android.view.Gravity; import android.view.Gravity; import android.view.View; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout; import android.widget.Space; import android.widget.Space; import com.android.systemui.R; import com.android.systemui.R; Loading Loading @@ -103,7 +101,7 @@ public class QuickQSPanel extends QSPanel { private static class HeaderTileLayout extends LinearLayout implements QSTileLayout { private static class HeaderTileLayout extends LinearLayout implements QSTileLayout { private final ImageView mDownArrow; private final Space mEndSpacer; public HeaderTileLayout(Context context) { public HeaderTileLayout(Context context) { super(context); super(context); Loading @@ -112,16 +110,10 @@ public class QuickQSPanel extends QSPanel { setGravity(Gravity.CENTER_VERTICAL); setGravity(Gravity.CENTER_VERTICAL); setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); int padding = mEndSpacer = new Space(context); mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding); mEndSpacer.setLayoutParams(generateLayoutParams()); 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); updateDownArrowMargin(); updateDownArrowMargin(); addView(mDownArrow); addView(mEndSpacer); setOrientation(LinearLayout.HORIZONTAL); setOrientation(LinearLayout.HORIZONTAL); } } Loading @@ -132,10 +124,10 @@ public class QuickQSPanel extends QSPanel { } } private void updateDownArrowMargin() { private void updateDownArrowMargin() { LayoutParams params = (LayoutParams) mDownArrow.getLayoutParams(); LayoutParams params = (LayoutParams) mEndSpacer.getLayoutParams(); params.setMarginStart(mContext.getResources().getDimensionPixelSize( params.setMarginStart(mContext.getResources().getDimensionPixelSize( R.dimen.qs_expand_margin)); R.dimen.qs_expand_margin)); mDownArrow.setLayoutParams(params); mEndSpacer.setLayoutParams(params); } } @Override @Override Loading packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java 0 → 100644 +241 −0 Original line number Original line Diff line number Diff line /* * 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<Object> mTargets = new ArrayList<>(); private List<Property> mProperties = new ArrayList<>(); private List<KeyframeSet> mValues = new ArrayList<>(); private float mStartDelay; private float mEndDelay; private Interpolator mInterpolator; private Listener mListener; public Builder addFloat(Object target, String property, float... values) { add(target, property, KeyframeSet.ofFloat(values)); return this; } public Builder addInt(Object target, String property, int... values) { add(target, property, KeyframeSet.ofInt(values)); return this; } 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)); mValues.add(keyframeSet); } public Builder setStartDelay(float startDelay) { mStartDelay = startDelay; return this; } public Builder setEndDelay(float endDelay) { mEndDelay = endDelay; return this; } public Builder setInterpolator(Interpolator intepolator) { mInterpolator = intepolator; return this; } public Builder setListener(Listener listener) { mListener = listener; return this; } public TouchAnimator build() { return new TouchAnimator(mTargets.toArray(new Object[mTargets.size()]), mProperties.toArray(new Property[mProperties.size()]), mValues.toArray(new KeyframeSet[mValues.size()]), mStartDelay, mEndDelay, mInterpolator, mListener); } } private static abstract class KeyframeSet { private final Keyframe[] mKeyframes; public KeyframeSet(Keyframe[] keyframes) { mKeyframes = keyframes; } 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); } protected abstract Object interpolate(Keyframe first, Keyframe second, 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); } 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); } } public static class FloatKeyframeSet extends KeyframeSet { public FloatKeyframeSet(Keyframe[] keyframes) { super(keyframes); } @Override protected Object interpolate(Keyframe first, Keyframe second, float amount) { float firstFloat = (float) first.getValue(); float secondFloat = (float) second.getValue(); return firstFloat + (secondFloat - firstFloat) * amount; } } public static class IntKeyframeSet extends KeyframeSet { public IntKeyframeSet(Keyframe[] keyframes) { super(keyframes); } @Override protected Object interpolate(Keyframe first, Keyframe second, float amount) { int firstFloat = (int) first.getValue(); int secondFloat = (int) second.getValue(); return (int) (firstFloat + (secondFloat - firstFloat) * amount); } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java 0 → 100644 +50 −0 Original line number Original line Diff line number Diff line /* * 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.statusbar.phone; import android.content.Context; import android.graphics.drawable.AnimatedVectorDrawable; import android.util.AttributeSet; import android.widget.ImageView; import com.android.systemui.R; public class ExpandableIndicator extends ImageView { private boolean mExpanded; public ExpandableIndicator(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); final int res = mExpanded ? R.drawable.ic_volume_collapse_animation : R.drawable.ic_volume_expand_animation; setImageResource(res); } public void setExpanded(boolean expanded) { if (expanded == mExpanded) return; mExpanded = expanded; final int res = mExpanded ? R.drawable.ic_volume_expand_animation : R.drawable.ic_volume_collapse_animation; // workaround to reset drawable final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getContext() .getDrawable(res).getConstantState().newDrawable(); setImageDrawable(avd); avd.start(); } } Loading
packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml +5 −6 Original line number Original line Diff line number Diff line Loading @@ -32,7 +32,6 @@ > > <LinearLayout <LinearLayout android:id="@+id/expanded_group" android:layout_width="wrap_content" android:layout_width="wrap_content" android:layout_height="48dp" android:layout_height="48dp" android:gravity="center" android:gravity="center" Loading Loading @@ -80,12 +79,12 @@ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> <ImageView <com.android.systemui.statusbar.phone.ExpandableIndicator android:id="@+id/expand_indicator" android:layout_width="48dp" android:layout_width="48dp" android:layout_height="48dp" android:layout_height="48dp" android:padding="12dp" android:padding="12dp" /> android:src="@drawable/ic_expand_less" android:tint="@android:color/white" /> </LinearLayout> </LinearLayout> <TextView <TextView Loading @@ -109,6 +108,7 @@ android:layout_height="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_alignParentTop="true" android:layout_marginTop="4dp" android:layout_marginStart="16dp" android:layout_marginStart="16dp" android:gravity="start" android:gravity="start" android:orientation="vertical"> android:orientation="vertical"> Loading @@ -116,7 +116,6 @@ android:id="@+id/date_time_group" android:id="@+id/date_time_group" android:layout_width="wrap_content" android:layout_width="wrap_content" android:layout_height="19dp" android:layout_height="19dp" android:layout_marginTop="4dp" android:orientation="horizontal"> android:orientation="horizontal"> <include layout="@layout/split_clock_view" <include layout="@layout/split_clock_view" Loading
packages/SystemUI/res/values/dimens.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,7 @@ <dimen name="qs_date_alarm_anim_translation">26dp</dimen> <dimen name="qs_date_alarm_anim_translation">26dp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_collapsed_text_size">14sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> <dimen name="qs_date_text_size">16sp</dimen> <dimen name="qs_header_gear_translation">120dp</dimen> <dimen name="qs_page_indicator_size">12dp</dimen> <dimen name="qs_page_indicator_size">12dp</dimen> <dimen name="qs_tile_icon_size">24dp</dimen> <dimen name="qs_tile_icon_size">24dp</dimen> <dimen name="qs_tile_text_size">12sp</dimen> <dimen name="qs_tile_text_size">12sp</dimen> Loading
packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +6 −14 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,10 @@ package com.android.systemui.qs; package com.android.systemui.qs; import android.content.Context; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Configuration; import android.util.AttributeSet; import android.util.AttributeSet; import android.view.Gravity; import android.view.Gravity; import android.view.View; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout; import android.widget.Space; import android.widget.Space; import com.android.systemui.R; import com.android.systemui.R; Loading Loading @@ -103,7 +101,7 @@ public class QuickQSPanel extends QSPanel { private static class HeaderTileLayout extends LinearLayout implements QSTileLayout { private static class HeaderTileLayout extends LinearLayout implements QSTileLayout { private final ImageView mDownArrow; private final Space mEndSpacer; public HeaderTileLayout(Context context) { public HeaderTileLayout(Context context) { super(context); super(context); Loading @@ -112,16 +110,10 @@ public class QuickQSPanel extends QSPanel { setGravity(Gravity.CENTER_VERTICAL); setGravity(Gravity.CENTER_VERTICAL); setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); int padding = mEndSpacer = new Space(context); mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding); mEndSpacer.setLayoutParams(generateLayoutParams()); 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); updateDownArrowMargin(); updateDownArrowMargin(); addView(mDownArrow); addView(mEndSpacer); setOrientation(LinearLayout.HORIZONTAL); setOrientation(LinearLayout.HORIZONTAL); } } Loading @@ -132,10 +124,10 @@ public class QuickQSPanel extends QSPanel { } } private void updateDownArrowMargin() { private void updateDownArrowMargin() { LayoutParams params = (LayoutParams) mDownArrow.getLayoutParams(); LayoutParams params = (LayoutParams) mEndSpacer.getLayoutParams(); params.setMarginStart(mContext.getResources().getDimensionPixelSize( params.setMarginStart(mContext.getResources().getDimensionPixelSize( R.dimen.qs_expand_margin)); R.dimen.qs_expand_margin)); mDownArrow.setLayoutParams(params); mEndSpacer.setLayoutParams(params); } } @Override @Override Loading
packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java 0 → 100644 +241 −0 Original line number Original line Diff line number Diff line /* * 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<Object> mTargets = new ArrayList<>(); private List<Property> mProperties = new ArrayList<>(); private List<KeyframeSet> mValues = new ArrayList<>(); private float mStartDelay; private float mEndDelay; private Interpolator mInterpolator; private Listener mListener; public Builder addFloat(Object target, String property, float... values) { add(target, property, KeyframeSet.ofFloat(values)); return this; } public Builder addInt(Object target, String property, int... values) { add(target, property, KeyframeSet.ofInt(values)); return this; } 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)); mValues.add(keyframeSet); } public Builder setStartDelay(float startDelay) { mStartDelay = startDelay; return this; } public Builder setEndDelay(float endDelay) { mEndDelay = endDelay; return this; } public Builder setInterpolator(Interpolator intepolator) { mInterpolator = intepolator; return this; } public Builder setListener(Listener listener) { mListener = listener; return this; } public TouchAnimator build() { return new TouchAnimator(mTargets.toArray(new Object[mTargets.size()]), mProperties.toArray(new Property[mProperties.size()]), mValues.toArray(new KeyframeSet[mValues.size()]), mStartDelay, mEndDelay, mInterpolator, mListener); } } private static abstract class KeyframeSet { private final Keyframe[] mKeyframes; public KeyframeSet(Keyframe[] keyframes) { mKeyframes = keyframes; } 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); } protected abstract Object interpolate(Keyframe first, Keyframe second, 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); } 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); } } public static class FloatKeyframeSet extends KeyframeSet { public FloatKeyframeSet(Keyframe[] keyframes) { super(keyframes); } @Override protected Object interpolate(Keyframe first, Keyframe second, float amount) { float firstFloat = (float) first.getValue(); float secondFloat = (float) second.getValue(); return firstFloat + (secondFloat - firstFloat) * amount; } } public static class IntKeyframeSet extends KeyframeSet { public IntKeyframeSet(Keyframe[] keyframes) { super(keyframes); } @Override protected Object interpolate(Keyframe first, Keyframe second, float amount) { int firstFloat = (int) first.getValue(); int secondFloat = (int) second.getValue(); return (int) (firstFloat + (secondFloat - firstFloat) * amount); } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java 0 → 100644 +50 −0 Original line number Original line Diff line number Diff line /* * 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.statusbar.phone; import android.content.Context; import android.graphics.drawable.AnimatedVectorDrawable; import android.util.AttributeSet; import android.widget.ImageView; import com.android.systemui.R; public class ExpandableIndicator extends ImageView { private boolean mExpanded; public ExpandableIndicator(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); final int res = mExpanded ? R.drawable.ic_volume_collapse_animation : R.drawable.ic_volume_expand_animation; setImageResource(res); } public void setExpanded(boolean expanded) { if (expanded == mExpanded) return; mExpanded = expanded; final int res = mExpanded ? R.drawable.ic_volume_expand_animation : R.drawable.ic_volume_collapse_animation; // workaround to reset drawable final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) getContext() .getDrawable(res).getConstantState().newDrawable(); setImageDrawable(avd); avd.start(); } }