KeyguardMultiUserAvatar.java revision 25a272a9f6323f6a3513bb522d45e839449878ce
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.policy.impl.keyguard; 18 19import android.animation.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.animation.ValueAnimator.AnimatorUpdateListener; 22import android.animation.ValueAnimator; 23import android.content.Context; 24import android.content.pm.UserInfo; 25import android.content.res.Resources; 26import android.graphics.Bitmap; 27import android.graphics.BitmapFactory; 28import android.graphics.Color; 29import android.util.AttributeSet; 30import android.util.Log; 31import android.view.LayoutInflater; 32import android.view.View; 33import android.widget.FrameLayout; 34import android.widget.ImageView; 35import android.widget.TextView; 36 37import com.android.internal.R; 38 39class KeyguardMultiUserAvatar extends FrameLayout { 40 private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName(); 41 private static final boolean DEBUG = KeyguardHostView.DEBUG; 42 43 private ImageView mUserImage; 44 private TextView mUserName; 45 private UserInfo mUserInfo; 46 private static final float ACTIVE_ALPHA = 1.0f; 47 private static final float INACTIVE_ALPHA = 1.0f; 48 private static final float ACTIVE_SCALE = 1.5f; 49 private static final float ACTIVE_TEXT_ALPHA = 0f; 50 private static final float INACTIVE_TEXT_ALPHA = 0.5f; 51 private static final int SWITCH_ANIMATION_DURATION = 150; 52 53 private final float mActiveAlpha; 54 private final float mActiveScale; 55 private final float mActiveTextAlpha; 56 private final float mInactiveAlpha; 57 private final float mInactiveTextAlpha; 58 private final float mShadowRadius; 59 private final float mStroke; 60 private final float mIconSize; 61 private final int mFrameColor; 62 private final int mFrameShadowColor; 63 private final int mTextColor; 64 private final int mHighlightColor; 65 66 private boolean mTouched; 67 68 private boolean mActive; 69 private boolean mInit = true; 70 private KeyguardMultiUserSelectorView mUserSelector; 71 private KeyguardCircleFramedDrawable mFramed; 72 private boolean mPressLock; 73 74 public static KeyguardMultiUserAvatar fromXml(int resId, Context context, 75 KeyguardMultiUserSelectorView userSelector, UserInfo info) { 76 KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar) 77 LayoutInflater.from(context).inflate(resId, userSelector, false); 78 79 icon.init(info, userSelector); 80 return icon; 81 } 82 83 public KeyguardMultiUserAvatar(Context context) { 84 this(context, null, 0); 85 } 86 87 public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) { 88 this(context, attrs, 0); 89 } 90 91 public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) { 92 super(context, attrs, defStyle); 93 94 Resources res = mContext.getResources(); 95 mTextColor = res.getColor(R.color.keyguard_avatar_nick_color); 96 mIconSize = res.getDimension(R.dimen.keyguard_avatar_size); 97 mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width); 98 mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius); 99 mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color); 100 mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color); 101 mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color); 102 mActiveTextAlpha = ACTIVE_TEXT_ALPHA; 103 mInactiveTextAlpha = INACTIVE_TEXT_ALPHA; 104 mActiveScale = ACTIVE_SCALE; 105 mActiveAlpha = ACTIVE_ALPHA; 106 mInactiveAlpha = INACTIVE_ALPHA; 107 108 mTouched = false; 109 110 setLayerType(View.LAYER_TYPE_SOFTWARE, null); 111 } 112 113 protected String rewriteIconPath(String path) { 114 if (!this.getClass().getName().contains("internal")) { 115 return path.replace("system", "data"); 116 } 117 return path; 118 } 119 120 public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) { 121 mUserInfo = user; 122 mUserSelector = userSelector; 123 124 mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar); 125 mUserName = (TextView) findViewById(R.id.keyguard_user_name); 126 127 Bitmap icon = null; 128 try { 129 icon = BitmapFactory.decodeFile(rewriteIconPath(user.iconPath)); 130 } catch (Exception e) { 131 if (DEBUG) Log.d(TAG, "failed to open profile icon " + user.iconPath, e); 132 } 133 134 if (icon == null) { 135 icon = BitmapFactory.decodeResource(mContext.getResources(), 136 com.android.internal.R.drawable.ic_contact_picture); 137 } 138 139 mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke, 140 mFrameShadowColor, mShadowRadius, mHighlightColor); 141 mUserImage.setImageDrawable(mFramed); 142 mUserName.setText(mUserInfo.name); 143 setOnClickListener(mUserSelector); 144 mInit = false; 145 } 146 147 public void setActive(boolean active, boolean animate, final Runnable onComplete) { 148 if (mActive != active || mInit) { 149 mActive = active; 150 151 if (active) { 152 KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent(); 153 parent.setTopChild(this); 154 // TODO: Create an appropriate asset when string changes are possible. 155 setContentDescription(mUserName.getText() 156 + ". " + mContext.getString(R.string.user_switched, "")); 157 } else { 158 setContentDescription(mUserName.getText()); 159 } 160 } 161 updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete); 162 } 163 164 void updateVisualsForActive(boolean active, boolean animate, int duration, 165 final Runnable onComplete) { 166 final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha; 167 final float initAlpha = active ? mInactiveAlpha : mActiveAlpha; 168 final float finalScale = active ? 1f : 1f / mActiveScale; 169 final float initScale = mFramed.getScale(); 170 final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) : 171 (int) (mInactiveTextAlpha * 255); 172 final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) : 173 (int) (mActiveTextAlpha * 255); 174 int textColor = mTextColor; 175 mUserName.setTextColor(textColor); 176 177 if (animate && mTouched) { 178 ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); 179 va.addUpdateListener(new AnimatorUpdateListener() { 180 @Override 181 public void onAnimationUpdate(ValueAnimator animation) { 182 float r = animation.getAnimatedFraction(); 183 float scale = (1 - r) * initScale + r * finalScale; 184 float alpha = (1 - r) * initAlpha + r * finalAlpha; 185 int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha); 186 mFramed.setScale(scale); 187 mUserImage.setAlpha(alpha); 188 mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255)); 189 mUserImage.invalidate(); 190 } 191 }); 192 va.addListener(new AnimatorListenerAdapter() { 193 @Override 194 public void onAnimationEnd(Animator animation) { 195 if (onComplete != null) { 196 onComplete.run(); 197 } 198 } 199 }); 200 va.setDuration(duration); 201 va.start(); 202 } else { 203 mFramed.setScale(finalScale); 204 mUserImage.setAlpha(finalAlpha); 205 mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255)); 206 if (onComplete != null) { 207 post(onComplete); 208 } 209 } 210 211 mTouched = true; 212 } 213 214 @Override 215 public void setPressed(boolean pressed) { 216 if (mPressLock && !pressed) { 217 return; 218 } 219 220 if (mPressLock || !pressed || isClickable()) { 221 super.setPressed(pressed); 222 mFramed.setPressed(pressed); 223 mUserImage.invalidate(); 224 } 225 } 226 227 public void lockPressed(boolean pressed) { 228 mPressLock = pressed; 229 setPressed(pressed); 230 } 231 232 public UserInfo getUserInfo() { 233 return mUserInfo; 234 } 235} 236