QSTileView.java revision ece4a834e8ae6d7e7cf09cd3134a2acd8f8427bd
1af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/* 2af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Copyright (C) 2014 The Android Open Source Project 3af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 4af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * you may not use this file except in compliance with the License. 6af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * You may obtain a copy of the License at 7af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 8af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 10af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Unless required by applicable law or agreed to in writing, software 11af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * See the License for the specific language governing permissions and 14af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * limitations under the License. 15af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock */ 16af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 17af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockpackage com.android.systemui.qs; 18af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 19af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.Context; 20af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.res.Resources; 21af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.res.TypedArray; 22af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.graphics.Typeface; 23af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.graphics.drawable.Drawable; 244bf31983d247a76142937c01bc2800b7f98d0281John Spurlockimport android.graphics.drawable.RippleDrawable; 25af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Handler; 26af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Looper; 27af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Message; 28af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.util.TypedValue; 29af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.view.Gravity; 30af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.view.View; 31af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.view.ViewGroup; 3283e2848c562bf951fd49d85da338eb6dc459cff2John Spurlockimport android.widget.ImageView; 33af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.widget.ImageView.ScaleType; 34af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.widget.TextView; 35af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 36af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.R; 37af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.QSTile.State; 38af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 39af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/** View that represents a standard quick settings tile. **/ 40af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockpublic class QSTileView extends ViewGroup { 41af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed", 42af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock Typeface.NORMAL); 43af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 44af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final Context mContext; 45af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final View mIcon; 46af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final View mDivider; 47af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final H mHandler = new H(); 484bf31983d247a76142937c01bc2800b7f98d0281John Spurlock private final int mIconSizePx; 4992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock private final int mTileSpacingPx; 5092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock private final int mTilePaddingTopPx; 5192d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock private final int mTilePaddingBelowIconPx; 5239076ed379c293399292d1c6b799866c1321b44bJohn Spurlock private final int mDualTileVerticalPaddingPx; 53e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek private final View mTopBackgroundView; 54af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 55d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock private TextView mLabel; 5692d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock private QSDualTileLabel mDualLabel; 57af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private boolean mDual; 58af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private OnClickListener mClickPrimary; 59af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private OnClickListener mClickSecondary; 604bf31983d247a76142937c01bc2800b7f98d0281John Spurlock private RippleDrawable mRipple; 61af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 62af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public QSTileView(Context context) { 63af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock super(context); 64af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 65af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mContext = context; 66af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final Resources res = context.getResources(); 674bf31983d247a76142937c01bc2800b7f98d0281John Spurlock mIconSizePx = res.getDimensionPixelSize(R.dimen.qs_tile_icon_size); 6892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing); 6992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mTilePaddingTopPx = res.getDimensionPixelSize(R.dimen.qs_tile_padding_top); 7092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mTilePaddingBelowIconPx = res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon); 7139076ed379c293399292d1c6b799866c1321b44bJohn Spurlock mDualTileVerticalPaddingPx = 7239076ed379c293399292d1c6b799866c1321b44bJohn Spurlock res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical); 73d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock recreateLabel(); 74af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock setClipChildren(false); 75af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 76e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView = new View(context); 77e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek addView(mTopBackgroundView); 78e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek 79af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mIcon = createIcon(); 80af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock addView(mIcon); 81af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 82af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mDivider = new View(mContext); 834bf31983d247a76142937c01bc2800b7f98d0281John Spurlock mDivider.setBackgroundColor(res.getColor(R.color.qs_tile_divider)); 844bf31983d247a76142937c01bc2800b7f98d0281John Spurlock final int dh = res.getDimensionPixelSize(R.dimen.qs_tile_divider_height); 85af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mDivider.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, dh)); 86af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock addView(mDivider); 87af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 88af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock setClickable(true); 89af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 90af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 91d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock private void recreateLabel() { 92d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock CharSequence labelText = null; 93e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek CharSequence labelDescription = null; 94d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock if (mLabel != null) { 95d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock labelText = mLabel.getText(); 96d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock removeView(mLabel); 9792d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel = null; 9892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } 9992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock if (mDualLabel != null) { 10092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock labelText = mDualLabel.getText(); 101e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek labelDescription = mLabel.getContentDescription(); 10292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock removeView(mDualLabel); 10392d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel = null; 104d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock } 105d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock final Resources res = mContext.getResources(); 10692d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock if (mDual) { 10739076ed379c293399292d1c6b799866c1321b44bJohn Spurlock mDualLabel = new QSDualTileLabel(mContext); 10892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setId(android.R.id.title); 10939076ed379c293399292d1c6b799866c1321b44bJohn Spurlock mDualLabel.setBackgroundResource(R.drawable.btn_borderless_rect); 11092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setTextColor(res.getColor(R.color.qs_tile_text)); 11139076ed379c293399292d1c6b799866c1321b44bJohn Spurlock mDualLabel.setPadding(0, mDualTileVerticalPaddingPx, 0, mDualTileVerticalPaddingPx); 11292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setTypeface(CONDENSED); 11392d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 11492d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock res.getDimensionPixelSize(R.dimen.qs_tile_text_size)); 11592d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setClickable(true); 11692d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setOnClickListener(mClickSecondary); 117e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mDualLabel.setFocusable(true); 11892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock if (labelText != null) { 11992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setText(labelText); 12092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } 121e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek if (labelDescription != null) { 122e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek mDualLabel.setContentDescription(labelDescription); 123e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek } 12492d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock addView(mDualLabel); 12592d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } else { 12692d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel = new TextView(mContext); 12792d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setId(android.R.id.title); 12892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setTextColor(res.getColor(R.color.qs_tile_text)); 12992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setGravity(Gravity.CENTER_HORIZONTAL); 13092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setMinLines(2); 13192d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setPadding(0, 0, 0, 0); 13292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setTypeface(CONDENSED); 13392d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, 13492d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock res.getDimensionPixelSize(R.dimen.qs_tile_text_size)); 13592d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setClickable(false); 13692d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock if (labelText != null) { 13792d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setText(labelText); 13892d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } 13992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock addView(mLabel); 140d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock } 141d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock } 142d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock 143af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void setDual(boolean dual) { 144d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock final boolean changed = dual != mDual; 145af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mDual = dual; 146d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock if (changed) { 147d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock recreateLabel(); 148d47a3f3bbe5264061bf0c506976efafa0d0f2957John Spurlock } 149e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek Drawable tileBackground = getTileBackground(); 150e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek if (tileBackground instanceof RippleDrawable) { 151e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setRipple((RippleDrawable) tileBackground); 152e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } 153e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek if (dual) { 154e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.setOnClickListener(mClickPrimary); 155e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setOnClickListener(null); 156e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setClickable(false); 157e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); 158e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.setBackground(tileBackground); 159e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } else { 160e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.setOnClickListener(null); 161e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.setClickable(false); 162e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setOnClickListener(mClickPrimary); 163e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); 164e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setBackground(tileBackground); 165e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } 166e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.setFocusable(dual); 167e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek setFocusable(!dual); 168af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mDivider.setVisibility(dual ? VISIBLE : GONE); 169af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock postInvalidate(); 170af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 171af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 172e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek private void setRipple(RippleDrawable tileBackground) { 173e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mRipple = tileBackground; 174e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek if (getWidth() != 0) { 175e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek updateRippleSize(getWidth(), getHeight()); 176e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } 177e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } 178e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek 179af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void init(OnClickListener clickPrimary, OnClickListener clickSecondary) { 180af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mClickPrimary = clickPrimary; 181af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mClickSecondary = clickSecondary; 182af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 183af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 184af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected View createIcon() { 18583e2848c562bf951fd49d85da338eb6dc459cff2John Spurlock final ImageView icon = new ImageView(mContext); 186af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock icon.setId(android.R.id.icon); 187af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock icon.setScaleType(ScaleType.CENTER_INSIDE); 188af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return icon; 189af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 190af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 1914bf31983d247a76142937c01bc2800b7f98d0281John Spurlock private Drawable getTileBackground() { 192856edebad73560e9b1cce021a7de9a0470d07176John Spurlock final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless }; 193af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final TypedArray ta = mContext.obtainStyledAttributes(attrs); 194af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final Drawable d = ta.getDrawable(0); 195af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock ta.recycle(); 196af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return d; 197af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 198af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 19992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock private View labelView() { 20092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock return mDual ? mDualLabel : mLabel; 20192d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } 20292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock 203af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 204af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 205af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final int w = MeasureSpec.getSize(widthMeasureSpec); 206af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final int h = MeasureSpec.getSize(heightMeasureSpec); 2074bf31983d247a76142937c01bc2800b7f98d0281John Spurlock final int iconSpec = exactly(mIconSizePx); 208af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mIcon.measure(iconSpec, iconSpec); 20992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock labelView().measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST)); 210af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (mDual) { 211af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mDivider.measure(widthMeasureSpec, exactly(mDivider.getLayoutParams().height)); 212af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 213e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek int heightSpec = exactly( 214e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mIconSizePx + mTilePaddingBelowIconPx + mTilePaddingTopPx); 215e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mTopBackgroundView.measure(widthMeasureSpec, heightSpec); 216af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock setMeasuredDimension(w, h); 217af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 218af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 219af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static int exactly(int size) { 220af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 221af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 222af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 223af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 224af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void onLayout(boolean changed, int l, int t, int r, int b) { 225af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final int w = getMeasuredWidth(); 226529aa73af20204c21694fbeac9799eaa79f664f8John Spurlock final int h = getMeasuredHeight(); 227af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 228e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek layout(mTopBackgroundView, 0, mTileSpacingPx); 229e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek 23092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock int top = 0; 23192d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock top += mTileSpacingPx; 23292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock top += mTilePaddingTopPx; 233af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final int iconLeft = (w - mIcon.getMeasuredWidth()) / 2; 234af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock layout(mIcon, iconLeft, top); 2354bf31983d247a76142937c01bc2800b7f98d0281John Spurlock if (mRipple != null) { 236e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek updateRippleSize(w, h); 237e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek 2384bf31983d247a76142937c01bc2800b7f98d0281John Spurlock } 239af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock top = mIcon.getBottom(); 24092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock top += mTilePaddingBelowIconPx; 241af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (mDual) { 242af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock layout(mDivider, 0, top); 243af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock top = mDivider.getBottom(); 244af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 24592d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock layout(labelView(), 0, top); 246af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 247af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 248e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek private void updateRippleSize(int width, int height) { 249e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek // center the touch feedback on the center of the icon, and dial it down a bit 250e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek final int cx = width / 2; 251e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek final int cy = mDual ? mIcon.getTop() + mIcon.getHeight() / 2 : height / 2; 252e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek final int rad = (int)(mIcon.getHeight() * 1.25f); 253e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek mRipple.setHotspotBounds(cx - rad, cy - rad, cx + rad, cy + rad); 254e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek } 255e32010ac6120278fea41e49b9832af79b1b5463eSelim Cinek 256af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static void layout(View child, int left, int top) { 257af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight()); 258af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 259af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 260af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void handleStateChanged(QSTile.State state) { 26183e2848c562bf951fd49d85da338eb6dc459cff2John Spurlock if (mIcon instanceof ImageView) { 26283e2848c562bf951fd49d85da338eb6dc459cff2John Spurlock ImageView iv = (ImageView) mIcon; 263af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (state.icon != null) { 26483e2848c562bf951fd49d85da338eb6dc459cff2John Spurlock iv.setImageDrawable(state.icon); 265af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (state.iconId > 0) { 26683e2848c562bf951fd49d85da338eb6dc459cff2John Spurlock iv.setImageResource(state.iconId); 267af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 268af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 26992d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock if (mDual) { 27092d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mDualLabel.setText(state.label); 271e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek mDualLabel.setContentDescription(state.dualLabelContentDescription); 27292d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } else { 27392d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock mLabel.setText(state.label); 27492d9b19e1bc5f93ef31c4e6eb3395eaf78a5c84eJohn Spurlock } 275af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock setContentDescription(state.contentDescription); 276af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 277af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 278af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void onStateChanged(QSTile.State state) { 279af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget(); 280af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 281af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 282af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private class H extends Handler { 283af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static final int STATE_CHANGED = 1; 284af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public H() { 285af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock super(Looper.getMainLooper()); 286af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 287af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 288af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void handleMessage(Message msg) { 289af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (msg.what == STATE_CHANGED) { 290af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleStateChanged((State) msg.obj); 291af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 292af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 293af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 294ece4a834e8ae6d7e7cf09cd3134a2acd8f8427bdSelim Cinek} 295