1 /* 2 * Copyright (C) 2021 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 package com.android.keyguard; 17 18 import android.content.Context; 19 import android.content.res.ColorStateList; 20 import android.content.res.Configuration; 21 import android.content.res.TypedArray; 22 import android.graphics.drawable.Drawable; 23 import android.graphics.drawable.RippleDrawable; 24 import android.graphics.drawable.VectorDrawable; 25 import android.util.AttributeSet; 26 import android.view.MotionEvent; 27 28 import androidx.annotation.Nullable; 29 30 /** 31 * Similar to the {@link NumPadKey}, but displays an image. 32 */ 33 public class NumPadButton extends AlphaOptimizedImageButton { 34 35 @Nullable 36 private NumPadAnimator mAnimator; 37 private int mOrientation; 38 NumPadButton(Context context, AttributeSet attrs)39 public NumPadButton(Context context, AttributeSet attrs) { 40 super(context, attrs); 41 42 Drawable background = getBackground(); 43 if (background instanceof RippleDrawable) { 44 mAnimator = new NumPadAnimator(context, (RippleDrawable) getBackground(), 45 attrs.getStyleAttribute()); 46 } else { 47 mAnimator = null; 48 } 49 } 50 51 @Override onConfigurationChanged(Configuration newConfig)52 protected void onConfigurationChanged(Configuration newConfig) { 53 mOrientation = newConfig.orientation; 54 } 55 56 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)57 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 58 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 59 60 // Set width/height to the same value to ensure a smooth circle for the bg, but shrink 61 // the height to match the old pin bouncer. 62 // This is only used for PIN/PUK; the main PIN pad now uses ConstraintLayout, which will 63 // force our width/height to conform to the ratio in the layout. 64 int width = getMeasuredWidth(); 65 66 boolean shortenHeight = mAnimator == null 67 || mOrientation == Configuration.ORIENTATION_LANDSCAPE; 68 int height = shortenHeight ? (int) (width * .66f) : width; 69 70 setMeasuredDimension(getMeasuredWidth(), height); 71 } 72 73 @Override onLayout(boolean changed, int l, int t, int r, int b)74 protected void onLayout(boolean changed, int l, int t, int r, int b) { 75 super.onLayout(changed, l, t, r, b); 76 77 if (mAnimator != null) mAnimator.onLayout(b - t); 78 } 79 80 @Override onTouchEvent(MotionEvent event)81 public boolean onTouchEvent(MotionEvent event) { 82 if (event.getActionMasked() == MotionEvent.ACTION_DOWN && mAnimator != null) { 83 mAnimator.start(); 84 } 85 return super.onTouchEvent(event); 86 } 87 88 /** 89 * Reload colors from resources. 90 **/ reloadColors()91 public void reloadColors() { 92 if (mAnimator != null) mAnimator.reloadColors(getContext()); 93 94 int[] customAttrs = {android.R.attr.textColorPrimaryInverse}; 95 TypedArray a = getContext().obtainStyledAttributes(customAttrs); 96 int imageColor = a.getColor(0, 0); 97 a.recycle(); 98 ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor)); 99 } 100 } 101