Keyguard polish

-> Updated user switcher to be closer to spec (issue 7047393)
-> Drawing keyguard overscroll gradient manually in KeyguardWidgetFrame
   (eliminates need for assets, eliminates banding)
-> Fixed clipping of overscroll on sw600dp using negative margin

Change-Id: I90ec7f820ca7dccebf7e05628a3185e95d41af08
This commit is contained in:
Adam Cohen
2012-10-02 21:42:54 -07:00
parent 891a216102
commit 61cd69c378
10 changed files with 132 additions and 86 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -22,6 +22,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="125dp"
android:layout_height="125dp"
android:background="#000000"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/keyguard_user_avatar"
@ -29,12 +30,23 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<TextView
android:id="@+id/keyguard_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:textSize="12sp"
android:background="#99FFFFFF"
android:textColor="#ff000000"/>
</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.78" />
<TextView
android:id="@+id/keyguard_user_name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.22"
android:paddingLeft="6dp"
android:layout_gravity="center_vertical|left"
android:textSize="16sp"
android:textColor="#ffffff"
android:background="#808080" />
</LinearLayout>
</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>

View File

@ -38,7 +38,8 @@
android:layout_height="10dp"
android:orientation="horizontal"
android:paddingLeft="@dimen/kg_widget_pager_horizontal_padding"
android:paddingRight="@dimen/kg_widget_pager_horizontal_padding">
android:paddingRight="@dimen/kg_widget_pager_horizontal_padding"
android:layout_marginTop="@dimen/kg_runway_lights_top_margin">
<com.android.internal.policy.impl.keyguard.KeyguardGlowStripView
android:id="@+id/left_strip"
android:paddingTop="@dimen/kg_runway_lights_vertical_padding"

View File

@ -77,5 +77,13 @@
<!-- Preference fragment padding, sides -->
<dimen name="preference_fragment_padding_side">24dp</dimen>
<dimen name="preference_screen_header_padding_side">24dip</dimen>
<!-- Keyguard dimensions -->
<!-- Bottom padding for the widget pager -->
<dimen name="kg_widget_pager_bottom_padding">16dp</dimen>
<!-- Top margin for the runway lights. We add a negative margin in large
devices to account for the widget pager padding -->
<dimen name="kg_runway_lights_top_margin">-10dp</dimen>
</resources>

View File

@ -115,6 +115,11 @@
<color name="lockscreen_clock_am_pm">#ffffffff</color>
<color name="lockscreen_owner_info">#ff9a9a9a</color>
<!-- keyguard overscroll widget pager -->
<color name="kg_multi_user_text_active">#ffffffff</color>
<color name="kg_multi_user_text_inactive">#ff808080</color>
<color name="kg_widget_pager_gradient">#ff33B5E5</color>
<!-- FaceLock -->
<color name="facelock_spotlight_mask">#CC000000</color>

View File

@ -286,7 +286,7 @@
<dimen name="kg_runway_lights_height">7dp</dimen>
<!-- The height of the runway lights strip -->
<dimen name="kg_runway_lights_vertical_padding">3dp</dimen>
<dimen name="kg_runway_lights_vertical_padding">2dp</dimen>
<!-- Horizontal padding for the widget pager -->
<dimen name="kg_widget_pager_horizontal_padding">16dp</dimen>
@ -297,6 +297,10 @@
<!-- Bottom padding for the widget pager -->
<dimen name="kg_widget_pager_bottom_padding">6dp</dimen>
<!-- Top margin for the runway lights. We add a negative margin in large
devices to account for the widget pager padding -->
<dimen name="kg_runway_lights_top_margin">0dp</dimen>
<!-- Touch slop for the global toggle accessibility gesture -->
<dimen name="accessibility_touch_slop">80dip</dimen>

View File

@ -1188,6 +1188,9 @@
<java-symbol type="bool" name="config_reverseDefaultRotation" />
<java-symbol type="bool" name="config_showNavigationBar" />
<java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
<java-symbol type="color" name="kg_multi_user_text_active" />
<java-symbol type="color" name="kg_multi_user_text_inactive" />
<java-symbol type="color" name="kg_widget_pager_gradient" />
<java-symbol type="dimen" name="navigation_bar_height" />
<java-symbol type="dimen" name="navigation_bar_height_landscape" />
<java-symbol type="dimen" name="navigation_bar_width" />
@ -1213,8 +1216,6 @@
<java-symbol type="drawable" name="magnified_region_frame" />
<java-symbol type="drawable" name="menu_background" />
<java-symbol type="drawable" name="stat_sys_secure" />
<java-symbol type="drawable" name="kg_widget_overscroll_layer_left" />
<java-symbol type="drawable" name="kg_widget_overscroll_layer_right" />
<java-symbol type="id" name="action_mode_bar_stub" />
<java-symbol type="id" name="alarm_status" />
<java-symbol type="id" name="backspace" />

View File

@ -22,11 +22,11 @@ import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@ -38,9 +38,13 @@ class KeyguardMultiUserAvatar extends FrameLayout {
private ImageView mUserImage;
private TextView mUserName;
private UserInfo mUserInfo;
private static final int INACTIVE_COLOR = 85;
private static final int INACTIVE_ALPHA = 195;
private static final float ACTIVE_SCALE = 1.1f;
private static final float ACTIVE_ALPHA = 1.0f;
private static final float INACTIVE_ALPHA = 0.5f;
private static final float ACTIVE_SCALE = 1.2f;
private static final float ACTIVE_TEXT_BACGROUND_ALPHA = 0.5f;
private static final float INACTIVE_TEXT_BACGROUND_ALPHA = 0f;
private static int mActiveTextColor;
private static int mInactiveTextColor;
private boolean mActive;
private boolean mInit = true;
private KeyguardMultiUserSelectorView mUserSelector;
@ -67,6 +71,10 @@ class KeyguardMultiUserAvatar extends FrameLayout {
public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Resources res = context.getResources();
mActiveTextColor = res.getColor(R.color.kg_multi_user_text_active);
mInactiveTextColor = res.getColor(R.color.kg_multi_user_text_inactive);
}
public void setup(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
@ -89,51 +97,61 @@ class KeyguardMultiUserAvatar extends FrameLayout {
public void setActive(boolean active, boolean animate, int duration, final Runnable onComplete) {
if (mActive != active || mInit) {
mActive = active;
final int finalFilterAlpha = mActive ? 0 : INACTIVE_ALPHA;
final int initFilterAlpha = mActive ? INACTIVE_ALPHA : 0;
final float finalScale = mActive ? ACTIVE_SCALE : 1.0f;
final float initScale = mActive ? 1.0f : ACTIVE_SCALE;
if (active) {
KeyguardSubdivisionLayout parent = (KeyguardSubdivisionLayout) getParent();
parent.setTopChild(parent.indexOfChild(this));
}
}
updateVisualsForActive(mActive, animate, duration, true, onComplete);
}
if (animate) {
ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
va.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float r = animation.getAnimatedFraction();
float scale = (1 - r) * initScale + r * finalScale;
int filterAlpha = (int) ((1 - r) * initFilterAlpha + r * finalFilterAlpha);
setScaleX(scale);
setScaleY(scale);
mUserImage.setColorFilter(Color.argb(filterAlpha, INACTIVE_COLOR,
INACTIVE_COLOR, INACTIVE_COLOR));
mUserSelector.invalidate();
void updateVisualsForActive(boolean active, boolean animate, int duration, boolean scale,
final Runnable onComplete) {
final float finalAlpha = active ? ACTIVE_ALPHA : INACTIVE_ALPHA;
final float initAlpha = active ? INACTIVE_ALPHA : ACTIVE_ALPHA;
final float finalScale = active && scale ? ACTIVE_SCALE : 1.0f;
final float initScale = active ? 1.0f : ACTIVE_SCALE;
final int finalTextBgAlpha = active ? (int) (ACTIVE_TEXT_BACGROUND_ALPHA * 255) :
(int) (INACTIVE_TEXT_BACGROUND_ALPHA * 255);
final int initTextBgAlpha = active ? (int) (INACTIVE_TEXT_BACGROUND_ALPHA * 255) :
(int) (ACTIVE_TEXT_BACGROUND_ALPHA * 255);
int textColor = active ? mActiveTextColor : mInactiveTextColor;
mUserName.setTextColor(textColor);
}
});
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (onComplete != null) {
onComplete.run();
}
}
});
va.setDuration(duration);
va.start();
} else {
setScaleX(finalScale);
setScaleY(finalScale);
mUserImage.setColorFilter(Color.argb(finalFilterAlpha, INACTIVE_COLOR,
INACTIVE_COLOR, INACTIVE_COLOR));
if (onComplete != null) {
post(onComplete);
if (animate) {
ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
va.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float r = animation.getAnimatedFraction();
float scale = (1 - r) * initScale + r * finalScale;
float alpha = (1 - r) * initAlpha + r * finalAlpha;
int textBgAlpha = (int) ((1 - r) * initTextBgAlpha + r * finalTextBgAlpha);
setScaleX(scale);
setScaleY(scale);
mUserImage.setAlpha(alpha);
mUserName.setBackgroundColor(Color.argb(textBgAlpha, 0, 0, 0));
mUserSelector.invalidate();
}
});
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (onComplete != null) {
onComplete.run();
}
}
});
va.setDuration(duration);
va.start();
} else {
setScaleX(finalScale);
setScaleY(finalScale);
mUserImage.setAlpha(finalAlpha);
mUserName.setBackgroundColor(Color.argb(finalTextBgAlpha, 0, 0, 0));
if (onComplete != null) {
post(onComplete);
}
}
}
@ -156,13 +174,7 @@ class KeyguardMultiUserAvatar extends FrameLayout {
public void setPressed(boolean pressed) {
if (!mPressedStateLocked) {
super.setPressed(pressed);
if (pressed) {
mUserImage.setColorFilter(Color.argb(0, INACTIVE_COLOR,
INACTIVE_COLOR, INACTIVE_COLOR));
} else if (!mActive) {
mUserImage.setColorFilter(Color.argb(INACTIVE_ALPHA, INACTIVE_COLOR,
INACTIVE_COLOR, INACTIVE_COLOR));
}
updateVisualsForActive(pressed || mActive, false, 0, mActive, null);
} else {
mTempPressedStateHolder = pressed;
}

View File

@ -19,12 +19,13 @@ package com.android.internal.policy.impl.keyguard;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.FrameLayout;
@ -33,10 +34,14 @@ import com.android.internal.R;
public class KeyguardWidgetFrame extends FrameLayout {
private final static PorterDuffXfermode sAddBlendMode =
new PorterDuffXfermode(PorterDuff.Mode.ADD);
private static Drawable sLeftOverscrollDrawable;
private static Drawable sRightOverscrollDrawable;
private Drawable mForegroundDrawable;
private int mGradientColor;
private LinearGradient mForegroundGradient;
private LinearGradient mLeftToRightGradient;
private LinearGradient mRightToLeftGradient;
private Paint mGradientPaint = new Paint();
boolean mLeftToRight = true;
private float mOverScrollAmount = 0f;
private final Rect mForegroundRect = new Rect();
private int mForegroundAlpha = 0;
@ -52,27 +57,25 @@ public class KeyguardWidgetFrame extends FrameLayout {
public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Resources res = context.getResources();
if (sLeftOverscrollDrawable == null) {
sLeftOverscrollDrawable = res.getDrawable(R.drawable.kg_widget_overscroll_layer_left);
sRightOverscrollDrawable = res.getDrawable(R.drawable.kg_widget_overscroll_layer_right);
}
int hPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_horizontal_padding);
int topPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_top_padding);
int bottomPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);
setPadding(hPadding, topPadding, hPadding, bottomPadding);
mGradientColor = res.getColor(R.color.kg_widget_pager_gradient);
mGradientPaint.setXfermode(sAddBlendMode);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mForegroundAlpha > 0) {
mForegroundDrawable.setBounds(mForegroundRect);
Paint p = ((NinePatchDrawable) mForegroundDrawable).getPaint();
p.setXfermode(sAddBlendMode);
mForegroundDrawable.draw(canvas);
p.setXfermode(null);
}
drawGradientOverlay(canvas);
}
private void drawGradientOverlay(Canvas c) {
mGradientPaint.setShader(mForegroundGradient);
mGradientPaint.setAlpha(mForegroundAlpha);
c.drawRect(mForegroundRect, mGradientPaint);
}
@Override
@ -80,19 +83,19 @@ public class KeyguardWidgetFrame extends FrameLayout {
super.onSizeChanged(w, h, oldw, oldh);
mForegroundRect.set(getPaddingLeft(), getPaddingTop(),
w - getPaddingRight(), h - getPaddingBottom());
float x0 = mLeftToRight ? 0 : mForegroundRect.width();
float x1 = mLeftToRight ? mForegroundRect.width(): 0;
mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f,
mGradientColor, 0, Shader.TileMode.CLAMP);
mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
mGradientColor, 0, Shader.TileMode.CLAMP);
}
void setOverScrollAmount(float r, boolean left) {
if (Float.compare(mOverScrollAmount, r) != 0) {
mOverScrollAmount = r;
if (left && mForegroundDrawable != sLeftOverscrollDrawable) {
mForegroundDrawable = sLeftOverscrollDrawable;
} else if (!left && mForegroundDrawable != sRightOverscrollDrawable) {
mForegroundDrawable = sRightOverscrollDrawable;
}
mForegroundAlpha = (int) Math.round((r * 255));
mForegroundDrawable.setAlpha(mForegroundAlpha);
mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient;
mForegroundAlpha = (int) Math.round((0.85f * r * 255));
if (getLayerType() != LAYER_TYPE_HARDWARE) {
setLayerType(LAYER_TYPE_HARDWARE, null);
}