Changed the visual appearance of the speedbump view.

The colorfulldots are replaced by a simple line to avoid
catching too much attention.

Bug: 15188625
Change-Id: I41be50dcc61d495f3bc88e4731388f770fda83d0
This commit is contained in:
Selim Cinek
2014-06-11 20:03:14 +02:00
committed by Dan Sandler
parent 486ed08899
commit 1e119db1a3
10 changed files with 33 additions and 657 deletions

View File

@@ -18,48 +18,13 @@
<com.android.systemui.statusbar.SpeedBumpView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:clickable="true"
android:layout_height="@dimen/speed_bump_height"
android:visibility="gone"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/speed_bump_height_collapsed"
android:layout_gravity="top"
android:orientation="horizontal">
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/speedbump_line_left"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:background="#6fdddddd"
android:layout_gravity="center_vertical"/>
<com.android.systemui.statusbar.SpeedBumpDotsLayout
android:id="@+id/speed_bump_dots_layout"
android:layout_width="34dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_height="match_parent"
android:layout_weight="0"/>
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/speedbump_line_right"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:background="#6fdddddd"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<TextView
android:id="@+id/speed_bump_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:fontFamily="sans-serif-condensed"
android:textSize="15sp"
android:singleLine="true"
android:textColor="#eeeeee"
android:visibility="invisible"
android:text="@string/speed_bump_explanation"
android:paddingTop="4dp" />
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/speedbump_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#6fdddddd"
android:layout_gravity="center_vertical"/>
</com.android.systemui.statusbar.SpeedBumpView>

View File

@@ -45,18 +45,6 @@
<!-- Tint color for the content on the notification overflow card. -->
<color name="keyguard_overflow_content_color">#ff686868</color>
<!-- The color of the red speed bump dot -->
<color name="speed_bump_dot_red">#ffd50000</color>
<!-- The color of the blue speed bump dot -->
<color name="speed_bump_dot_blue">#ff2962ff</color>
<!-- The color of the yellow speed bump dot -->
<color name="speed_bump_dot_yellow">#ffffd600</color>
<!-- The color of the green speed bump dot -->
<color name="speed_bump_dot_green">#ff00c853</color>
<!-- The default recents task bar background color. -->
<color name="recents_task_bar_default_background_color">#e6444444</color>
<!-- The default recents task bar text color. -->

View File

@@ -275,14 +275,8 @@
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
<!-- The height of the collapsed speed bump view. -->
<dimen name="speed_bump_height_collapsed">24dp</dimen>
<!-- The padding inset the explanation text needs compared to the collapsed height -->
<dimen name="speed_bump_text_padding_inset">10dp</dimen>
<!-- The height of the speed bump dots. -->
<dimen name="speed_bump_dots_height">5dp</dimen>
<!-- The height of the speed bump view. -->
<dimen name="speed_bump_height">16dp</dimen>
<!-- The total height of the stack in its collapsed size (i.e. when quick settings is open) -->
<dimen name="collapsed_stack_height">94dp</dimen>

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2014 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;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* An single dot of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
*/
public class SpeedBumpDotView extends View {
private final Paint mPaint = new Paint();
public SpeedBumpDotView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
float radius = getWidth() / 2.0f;
canvas.drawCircle(radius, radius, radius, mPaint);
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
public void setColor(int color) {
mPaint.setColor(color);
}
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2014 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;
import android.content.Context;
import android.view.View;
import com.android.systemui.R;
/**
* The Algorithm of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} which can be
* queried for {@link * com.android.systemui.statusbar.SpeedBumpDotsState}
*/
public class SpeedBumpDotsAlgorithm {
private final float mDotRadius;
public SpeedBumpDotsAlgorithm(Context context) {
mDotRadius = context.getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height)
/ 2.0f;
}
public void getState(SpeedBumpDotsState resultState) {
// First reset the current state and ensure that every View has a ViewState
resultState.resetViewStates();
SpeedBumpDotsLayout hostView = resultState.getHostView();
boolean currentlyVisible = hostView.isCurrentlyVisible();
resultState.setActiveState(currentlyVisible
? SpeedBumpDotsState.SHOWN
: SpeedBumpDotsState.HIDDEN);
int hostWidth = hostView.getWidth();
float layoutWidth = hostWidth - 2 * mDotRadius;
int childCount = hostView.getChildCount();
float paddingBetween = layoutWidth / (childCount - 1);
float centerY = hostView.getHeight() / 2.0f;
for (int i = 0; i < childCount; i++) {
View child = hostView.getChildAt(i);
SpeedBumpDotsState.ViewState viewState = resultState.getViewStateForView(child);
if (currentlyVisible) {
float xTranslation = i * paddingBetween;
viewState.xTranslation = xTranslation;
viewState.yTranslation = calculateYTranslation(hostView, centerY, xTranslation,
layoutWidth);
} else {
viewState.xTranslation = layoutWidth / 2;
viewState.yTranslation = centerY - mDotRadius;
}
viewState.alpha = currentlyVisible ? 1.0f : 0.0f;
viewState.scale = currentlyVisible ? 1.0f : 0.5f;
}
}
private float calculateYTranslation(SpeedBumpDotsLayout hostView, float centerY,
float xTranslation, float layoutWidth) {
float t = hostView.getAnimationProgress();
if (t == 0.0f || t == 1.0f) {
return centerY - mDotRadius;
}
float damping = (0.5f -Math.abs(0.5f - t)) * 1.3f;
float partialOffset = xTranslation / layoutWidth;
float indentFactor = (float) (Math.sin((t + partialOffset * 1.5f) * - Math.PI) * damping);
return (1.0f - indentFactor) * centerY - mDotRadius;
}
}

View File

@@ -1,136 +0,0 @@
/*
* Copyright (C) 2014 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;
import android.animation.TimeAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.systemui.R;
/**
* A layout with a certain number of dots which are integrated in the
* {@link com.android.systemui.statusbar.SpeedBumpView}
*/
public class SpeedBumpDotsLayout extends ViewGroup {
private static final float DOT_CLICK_ANIMATION_LENGTH = 300;
private final int mDotSize;
private final SpeedBumpDotsAlgorithm mAlgorithm = new SpeedBumpDotsAlgorithm(getContext());
private final SpeedBumpDotsState mCurrentState = new SpeedBumpDotsState(this);
private boolean mIsCurrentlyVisible = true;
private final ValueAnimator mClickAnimator;
private float mAnimationProgress;
private ValueAnimator.AnimatorUpdateListener mClickUpdateListener
= new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimationProgress = animation.getAnimatedFraction();
updateChildren();
}
};
public SpeedBumpDotsLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mDotSize = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
createDots(context, attrs);
mClickAnimator = TimeAnimator.ofFloat(0, DOT_CLICK_ANIMATION_LENGTH);
mClickAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mClickAnimator.addUpdateListener(mClickUpdateListener);
}
private void createDots(Context context, AttributeSet attrs) {
SpeedBumpDotView blueDot = new SpeedBumpDotView(context, attrs);
blueDot.setColor(getResources().getColor(R.color.speed_bump_dot_blue));
addView(blueDot);
SpeedBumpDotView redDot = new SpeedBumpDotView(context, attrs);
redDot.setColor(getResources().getColor(R.color.speed_bump_dot_red));
addView(redDot);
SpeedBumpDotView yellowDot = new SpeedBumpDotView(context, attrs);
yellowDot.setColor(getResources().getColor(R.color.speed_bump_dot_yellow));
addView(yellowDot);
SpeedBumpDotView greenDot = new SpeedBumpDotView(context, attrs);
greenDot.setColor(getResources().getColor(R.color.speed_bump_dot_green));
addView(greenDot);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childWidthSpec = MeasureSpec.makeMeasureSpec(mDotSize,
MeasureSpec.getMode(widthMeasureSpec));
int childHeightSpec = MeasureSpec.makeMeasureSpec(mDotSize,
MeasureSpec.getMode(heightMeasureSpec));
measureChildren(childWidthSpec, childHeightSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.layout(0, 0, mDotSize, mDotSize);
}
if (changed) {
updateChildren();
}
}
private void updateChildren() {
mAlgorithm.getState(mCurrentState);
mCurrentState.apply();
}
public void performVisibilityAnimation(boolean visible) {
if (mClickAnimator.isRunning()) {
mClickAnimator.cancel();
}
mIsCurrentlyVisible = visible;
mAlgorithm.getState(mCurrentState);
mCurrentState.animateToState();
}
public void setInvisible() {
mIsCurrentlyVisible = false;
mAlgorithm.getState(mCurrentState);
mCurrentState.apply();
}
public boolean isCurrentlyVisible() {
return mIsCurrentlyVisible;
}
public void performDotClickAnimation() {
if (mClickAnimator.isRunning()) {
// don't perform an animation if it's running already
return;
}
mClickAnimator.start();
}
public float getAnimationProgress() {
return mAnimationProgress;
}
}

View File

@@ -1,128 +0,0 @@
/*
* Copyright (C) 2014 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;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import java.util.HashMap;
import java.util.Map;
/**
* A state of a {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
*/
public class SpeedBumpDotsState {
public static final int HIDDEN = 1;
public static final int SHOWN = 2;
private static final int VISIBILITY_ANIMATION_DELAY_PER_ELEMENT = 80;
private final SpeedBumpDotsLayout mHostView;
private final HashMap<View, ViewState> mStateMap = new HashMap<View, ViewState>();
private final Interpolator mFastOutSlowInInterpolator;
private int mActiveState = 0;
public SpeedBumpDotsState(SpeedBumpDotsLayout hostLayout) {
mHostView = hostLayout;
mFastOutSlowInInterpolator = AnimationUtils
.loadInterpolator(hostLayout.getContext(),
android.R.interpolator.fast_out_slow_in);
}
public SpeedBumpDotsLayout getHostView() {
return mHostView;
}
public void resetViewStates() {
int numChildren = mHostView.getChildCount();
for (int i = 0; i < numChildren; i++) {
View child = mHostView.getChildAt(i);
ViewState viewState = mStateMap.get(child);
if (viewState == null) {
viewState = new ViewState();
mStateMap.put(child, viewState);
}
}
}
public ViewState getViewStateForView(View requestedView) {
return mStateMap.get(requestedView);
}
public void apply() {
int childCount = mHostView.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = mHostView.getChildAt(i);
ViewState viewState = mStateMap.get(child);
child.setTranslationX(viewState.xTranslation);
child.setTranslationY(viewState.yTranslation);
child.setScaleX(viewState.scale);
child.setScaleY(viewState.scale);
child.setAlpha(viewState.alpha);
}
}
public void animateToState() {
int childCount = mHostView.getChildCount();
int middleIndex = (childCount - 1) / 2;
long delayPerElement = VISIBILITY_ANIMATION_DELAY_PER_ELEMENT;
boolean isAppearing = getActiveState() == SHOWN;
boolean isDisappearing = getActiveState() == HIDDEN;
for (int i = 0; i < childCount; i++) {
int delayIndex;
if (i <= middleIndex) {
delayIndex = i * 2;
} else {
int distToMiddle = i - middleIndex;
delayIndex = (childCount - 1) - (distToMiddle - 1) * 2;
}
long startDelay = 0;
if (isAppearing || isDisappearing) {
if (isDisappearing) {
delayIndex = childCount - 1 - delayIndex;
}
startDelay = delayIndex * delayPerElement;
}
View child = mHostView.getChildAt(i);
ViewState viewState = mStateMap.get(child);
child.animate().setInterpolator(mFastOutSlowInInterpolator)
.setStartDelay(startDelay)
.alpha(viewState.alpha)
.translationX(viewState.xTranslation)
.translationY(viewState.yTranslation)
.scaleX(viewState.scale).scaleY(viewState.scale);
}
}
public int getActiveState() {
return mActiveState;
}
public void setActiveState(int mActiveState) {
this.mActiveState = mActiveState;
}
public static class ViewState {
float xTranslation;
float yTranslation;
float alpha;
float scale;
}
}

View File

@@ -16,71 +16,26 @@
package com.android.systemui.statusbar;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Outline;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.TextView;
import com.android.systemui.R;
/**
* The view representing the separation between important and less important notifications
*/
public class SpeedBumpView extends ExpandableView implements View.OnClickListener {
public class SpeedBumpView extends ExpandableView {
private final int mCollapsedHeight;
private final int mDotsHeight;
private final int mTextPaddingInset;
private SpeedBumpDotsLayout mDots;
private AlphaOptimizedView mLineLeft;
private AlphaOptimizedView mLineRight;
private boolean mIsExpanded;
private boolean mDividerVisible = true;
private ValueAnimator mCurrentAnimator;
private final int mSpeedBumpHeight;
private AlphaOptimizedView mLine;
private boolean mIsVisible = true;
private final Interpolator mFastOutSlowInInterpolator;
private float mCenterX;
private TextView mExplanationText;
private boolean mExplanationTextVisible = false;
private AnimatorListenerAdapter mHideExplanationListener = new AnimatorListenerAdapter() {
private boolean mCancelled;
@Override
public void onAnimationEnd(Animator animation) {
if (!mCancelled) {
mExplanationText.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationCancel(Animator animation) {
mCancelled = true;
}
@Override
public void onAnimationStart(Animator animation) {
mCancelled = false;
}
};
private Animator.AnimatorListener mAnimationFinishedListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
};
public SpeedBumpView(Context context, AttributeSet attrs) {
super(context, attrs);
mCollapsedHeight = getResources()
.getDimensionPixelSize(R.dimen.speed_bump_height_collapsed);
mTextPaddingInset = getResources().getDimensionPixelSize(
R.dimen.speed_bump_text_padding_inset);
mDotsHeight = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
setOnClickListener(this);
mSpeedBumpHeight = getResources()
.getDimensionPixelSize(R.dimen.speed_bump_height);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
}
@@ -88,99 +43,34 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout);
mLineLeft = (AlphaOptimizedView) findViewById(R.id.speedbump_line_left);
mLineRight = (AlphaOptimizedView) findViewById(R.id.speedbump_line_right);
mExplanationText = (TextView) findViewById(R.id.speed_bump_text);
resetExplanationText();
mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line);
}
@Override
protected int getInitialHeight() {
return mCollapsedHeight;
return mSpeedBumpHeight;
}
@Override
public int getIntrinsicHeight() {
if (mCurrentAnimator != null) {
// expand animation is running
return getActualHeight();
}
return mIsExpanded ? getHeight() : mCollapsedHeight;
return mSpeedBumpHeight;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
Outline outline = new Outline();
mCenterX = getWidth() / 2;
float centerY = getHeight() / 2;
// TODO: hide outline better
// Temporary workaround to hide outline on a transparent view
int outlineLeft = (int) (mCenterX - getResources().getDisplayMetrics().densityDpi * 8);
int outlineTop = (int) (centerY - mDotsHeight / 2);
outline.setOval(outlineLeft, outlineTop, outlineLeft + mDotsHeight,
outlineTop + mDotsHeight);
setOutline(outline);
mLineLeft.setPivotX(mLineLeft.getWidth());
mLineLeft.setPivotY(mLineLeft.getHeight() / 2);
mLineRight.setPivotX(0);
mLineRight.setPivotY(mLineRight.getHeight() / 2);
mLine.setPivotX(mLine.getWidth() / 2);
mLine.setPivotY(mLine.getHeight() / 2);
setOutline(null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int height = mCollapsedHeight + mExplanationText.getMeasuredHeight() - mTextPaddingInset;
int height = mSpeedBumpHeight;
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
}
@Override
public void onClick(View v) {
if (mCurrentAnimator != null) {
return;
}
int startValue = mIsExpanded ? getMaxHeight() : mCollapsedHeight;
int endValue = mIsExpanded ? mCollapsedHeight : getMaxHeight();
mCurrentAnimator = ValueAnimator.ofInt(startValue, endValue);
mCurrentAnimator.setInterpolator(mFastOutSlowInInterpolator);
mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setActualHeight((int) animation.getAnimatedValue());
}
});
mCurrentAnimator.addListener(mAnimationFinishedListener);
mCurrentAnimator.start();
mIsExpanded = !mIsExpanded;
mDots.performDotClickAnimation();
animateExplanationTextInternal(mIsExpanded);
}
private void animateExplanationTextInternal(boolean visible) {
if (mExplanationTextVisible != visible) {
float translationY = 0.0f;
float scale = 0.5f;
float alpha = 0.0f;
boolean needsHideListener = true;
if (visible) {
mExplanationText.setVisibility(VISIBLE);
translationY = mDots.getBottom() - mTextPaddingInset;
scale = 1.0f;
alpha = 1.0f;
needsHideListener = false;
}
mExplanationText.animate().setInterpolator(mFastOutSlowInInterpolator)
.alpha(alpha)
.scaleX(scale)
.scaleY(scale)
.translationY(translationY)
.setListener(needsHideListener ? mHideExplanationListener : null);
mExplanationTextVisible = visible;
}
}
@Override
public boolean isTransparent() {
return true;
@@ -188,11 +78,6 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
public void performVisibilityAnimation(boolean nowVisible) {
animateDivider(nowVisible, null /* onFinishedRunnable */);
// Animate explanation Text
if (mIsExpanded) {
animateExplanationTextInternal(nowVisible);
}
}
/**
@@ -203,28 +88,16 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
* finished.
*/
public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) {
if (nowVisible != mDividerVisible) {
if (nowVisible != mIsVisible) {
// Animate dividers
float endValue = nowVisible ? 1.0f : 0.0f;
float endTranslationXLeft = nowVisible ? 0.0f : mCenterX - mLineLeft.getRight();
float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft();
mLineLeft.animate()
mLine.animate()
.alpha(endValue)
.scaleX(endValue)
.scaleY(endValue)
.translationX(endTranslationXLeft)
.setInterpolator(mFastOutSlowInInterpolator)
.withEndAction(onFinishedRunnable);
mLineRight.animate()
.alpha(endValue)
.scaleX(endValue)
.scaleY(endValue)
.translationX(endTranslationXRight)
.setInterpolator(mFastOutSlowInInterpolator);
// Animate dots
mDots.performVisibilityAnimation(nowVisible);
mDividerVisible = nowVisible;
mIsVisible = nowVisible;
} else {
if (onFinishedRunnable != null) {
onFinishedRunnable.run();
@@ -233,34 +106,10 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
}
public void setInvisible() {
float endTranslationXLeft = mCenterX - mLineLeft.getRight();
float endTranslationXRight = mCenterX - mLineRight.getLeft();
mLineLeft.setAlpha(0.0f);
mLineLeft.setScaleX(0.0f);
mLineLeft.setScaleY(0.0f);
mLineLeft.setTranslationX(endTranslationXLeft);
mLineRight.setAlpha(0.0f);
mLineRight.setScaleX(0.0f);
mLineRight.setScaleY(0.0f);
mLineRight.setTranslationX(endTranslationXRight);
mDots.setInvisible();
resetExplanationText();
mDividerVisible = false;
}
public void collapse() {
if (mIsExpanded) {
setActualHeight(mCollapsedHeight);
mIsExpanded = false;
}
resetExplanationText();
}
public void animateExplanationText(boolean nowVisible) {
if (mIsExpanded) {
animateExplanationTextInternal(nowVisible);
}
mLine.setAlpha(0.0f);
mLine.setScaleX(0.0f);
mLine.setScaleY(0.0f);
mIsVisible = false;
}
@Override
@@ -272,17 +121,4 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
public void performAddAnimation(long delay) {
performVisibilityAnimation(true);
}
private void resetExplanationText() {
mExplanationText.setTranslationY(0);
mExplanationText.setVisibility(INVISIBLE);
mExplanationText.setAlpha(0.0f);
mExplanationText.setScaleX(0.5f);
mExplanationText.setScaleY(0.5f);
mExplanationTextVisible = false;
}
public boolean isExpanded() {
return mIsExpanded;
}
}

View File

@@ -1723,7 +1723,6 @@ public class NotificationStackScrollLayout extends ViewGroup
mStackScrollAlgorithm.setIsExpanded(isExpanded);
if (!isExpanded) {
mOwnScrollY = 0;
mSpeedBumpView.collapse();
}
}
@@ -1792,7 +1791,6 @@ public class NotificationStackScrollLayout extends ViewGroup
int newVisibility = visible ? VISIBLE : GONE;
mSpeedBumpView.setVisibility(newVisibility);
if (visible) {
mSpeedBumpView.collapse();
// Make invisible to ensure that the appear animation is played.
mSpeedBumpView.setInvisible();
if (!mIsExpansionChanging) {

View File

@@ -160,9 +160,8 @@ public class StackScrollState {
}
if(child instanceof SpeedBumpView) {
float speedBumpEnd = newYTranslation + newHeight;
performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
newYTranslation);
float lineEnd = newYTranslation + newHeight / 2;
performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
}
}
}
@@ -183,20 +182,12 @@ public class StackScrollState {
child.setClipBounds(mClipRect);
}
private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
float speedBumpStart) {
private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) {
View nextChild = getNextChildNotGone(i);
if (nextChild != null) {
ViewState nextState = getViewStateForView(nextChild);
boolean startIsAboveNext = nextState.yTranslation > speedBumpStart;
boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd;
speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */);
// handle expanded case
if (speedBump.isExpanded()) {
boolean endIsAboveNext = nextState.yTranslation > speedBumpEnd;
speedBump.animateExplanationText(endIsAboveNext);
}
}
}