QSIconViewImpl.java revision 9a82d124628350e64a835043baffced59ffcd143
1dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk/* 2702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Copyright (C) 2017 The Android Open Source Project 3dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk * 4702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * except in compliance with the License. You may obtain a copy of the License at 6dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk * 7dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk * http://www.apache.org/licenses/LICENSE-2.0 8dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk * 9702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Unless required by applicable law or agreed to in writing, software distributed under the 10702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * KIND, either express or implied. See the License for the specific language governing 12702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * permissions and limitations under the License. 13dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk */ 14dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 15702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkpackage com.android.systemui.qs.tileimpl; 16dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 17702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport static com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState; 183250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 193250885c9feb9b42d60058a823c57a027c0dcf58Jason Monkimport android.animation.ValueAnimator; 20dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.content.Context; 213250885c9feb9b42d60058a823c57a027c0dcf58Jason Monkimport android.content.res.ColorStateList; 22dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.content.res.Resources; 233250885c9feb9b42d60058a823c57a027c0dcf58Jason Monkimport android.graphics.Color; 24dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.graphics.drawable.Animatable; 25dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.graphics.drawable.Drawable; 26dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.view.View; 27dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport android.widget.ImageView; 28eae7c318864bcfd814c8be697315f829952ccc69Jason Monkimport android.widget.ImageView.ScaleType; 293250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 30dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport com.android.systemui.R; 31702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSIconView; 32702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile; 33e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monkimport com.android.systemui.plugins.qs.QSTile.State; 34dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 35dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monkimport java.util.Objects; 36dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 37702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkpublic class QSIconViewImpl extends QSIconView { 38dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 392f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen protected final View mIcon; 402f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen protected final int mIconSizePx; 412f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen protected final int mTilePaddingBelowIconPx; 421aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk private boolean mAnimationEnabled = true; 433250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk private int mState = -1; 443250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk private int mTint; 45dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 46702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk public QSIconViewImpl(Context context) { 47dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk super(context); 48dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 49dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final Resources res = context.getResources(); 50dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk mIconSizePx = res.getDimensionPixelSize(R.dimen.qs_tile_icon_size); 51dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk mTilePaddingBelowIconPx = res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon); 52dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 53dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk mIcon = createIcon(); 54dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk addView(mIcon); 55dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 56dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 571aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk public void disableAnimation() { 581aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk mAnimationEnabled = false; 591aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk } 601aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk 612f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen public View getIconView() { 622f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen return mIcon; 632f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen } 642f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen 65dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk @Override 66dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 67dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final int w = MeasureSpec.getSize(widthMeasureSpec); 68dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final int iconSpec = exactly(mIconSizePx); 69dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk mIcon.measure(MeasureSpec.makeMeasureSpec(w, getIconMeasureMode()), iconSpec); 70dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk setMeasuredDimension(w, mIcon.getMeasuredHeight() + mTilePaddingBelowIconPx); 71dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 72dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 73dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk @Override 74dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk protected void onLayout(boolean changed, int l, int t, int r, int b) { 75dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final int w = getMeasuredWidth(); 76dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk int top = 0; 77dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final int iconLeft = (w - mIcon.getMeasuredWidth()) / 2; 78dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk layout(mIcon, iconLeft, top); 79dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 80dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 81dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk public void setIcon(QSTile.State state) { 82dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk setIcon((ImageView) mIcon, state); 83dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 84dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 85e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk protected void updateIcon(ImageView iv, State state) { 86dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) { 87da9395e681bfaa21692bcb4a7a249b1d7ff2e2d3Jason Monk boolean shouldAnimate = iv.isShown() && mAnimationEnabled 88da9395e681bfaa21692bcb4a7a249b1d7ff2e2d3Jason Monk && iv.getDrawable() != null; 891aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk Drawable d = state.icon != null 90da9395e681bfaa21692bcb4a7a249b1d7ff2e2d3Jason Monk ? shouldAnimate ? state.icon.getDrawable(mContext) 911aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk : state.icon.getInvisibleDrawable(mContext) : null; 92e19cc141c388c7190a1582f0ee72c9ba67569a2dJason Monk int padding = state.icon != null ? state.icon.getPadding() : 0; 93702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk if (d != null) { 94d686e9c26e84e56810fcf87f6002ba8ba2b3f0c5Jason Monk d.setAutoMirrored(false); 95dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 96dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk iv.setImageDrawable(d); 97dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk iv.setTag(R.id.qs_icon_tag, state.icon); 98b53b6c566f8e4754406cd1c3fddfa16a27515a7eJason Monk iv.setPadding(0, padding, 0, padding); 991aec93f1819369bda9e6cb0bd282419808c304c3Jason Monk if (d instanceof Animatable && iv.isShown()) { 100dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk Animatable a = (Animatable) d; 10166239fbdfce1586555b339854b8a21f8187e805fJason Monk a.start(); 10266239fbdfce1586555b339854b8a21f8187e805fJason Monk if (!iv.isShown()) { 103dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk a.stop(); // skip directly to end state 104dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 105dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 106dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 107e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 108e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk 109e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk protected void setIcon(ImageView iv, QSTile.State state) { 110e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk updateIcon(iv, state); 1111c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka if (state.disabledByPolicy) { 1121c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color)); 1131c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } else { 1141c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka iv.clearColorFilter(); 1151c7cda8bbfb848961536a4adbf2c81c5ffddae16Sudheer Shanka } 1163250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk if (state.state != mState) { 117e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk int color = getColor(state.state); 1183250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk mState = state.state; 1199a82d124628350e64a835043baffced59ffcd143Jason Monk if (iv.isShown() && mTint != 0) { 1203250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk animateGrayScale(mTint, color, iv); 1213250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk mTint = color; 1223250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk } else { 1233250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk setTint(iv, color); 1243250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk mTint = color; 1253250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk } 1263250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk } 1273250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk } 1283250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 129e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk protected int getColor(int state) { 130e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk return getColorForState(getContext(), state); 131e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk } 132e5b770e47d44a40d412c7d42010b2cf67920d9e3Jason Monk 1333250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk public static void animateGrayScale(int fromColor, int toColor, ImageView iv) { 1343250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk final float fromAlpha = Color.alpha(fromColor); 1353250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk final float toAlpha = Color.alpha(toColor); 1363250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk final float fromChannel = Color.red(fromColor); 1373250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk final float toChannel = Color.red(toColor); 1383250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 1393250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk ValueAnimator anim = ValueAnimator.ofFloat(0, 1); 1403250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk anim.setDuration(350); 1413250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 1423250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk anim.addUpdateListener(animation -> { 1433250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk float fraction = animation.getAnimatedFraction(); 1443250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk int alpha = (int) (fromAlpha + (toAlpha - fromAlpha) * fraction); 1453250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk int channel = (int) (fromChannel + (toChannel - fromChannel) * fraction); 1463250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 1473250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk setTint(iv, Color.argb(alpha, channel, channel, channel)); 1483250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk }); 1493250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk anim.start(); 150dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 151dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 1523250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk public static void setTint(ImageView iv, int color) { 1533250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk iv.setImageTintList(ColorStateList.valueOf(color)); 1543250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk } 1553250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 1563250885c9feb9b42d60058a823c57a027c0dcf58Jason Monk 157dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk protected int getIconMeasureMode() { 158dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk return MeasureSpec.EXACTLY; 159dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 160dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 161dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk protected View createIcon() { 162dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk final ImageView icon = new ImageView(mContext); 163dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk icon.setId(android.R.id.icon); 164eae7c318864bcfd814c8be697315f829952ccc69Jason Monk icon.setScaleType(ScaleType.FIT_CENTER); 165dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk return icon; 166dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 167dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 1682f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen protected final int exactly(int size) { 169dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 170dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 171dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk 1722f3551b04d5a5d05ba1eb7401f19c034708a9d00Xiaohui Chen protected final void layout(View child, int left, int top) { 173dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight()); 174dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk } 175dc35dcb14a8b6c4f221fccafffa5ca603894dbaaJason Monk} 176