1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.qs.tileimpl; 16 17 import android.content.Context; 18 import android.content.res.ColorStateList; 19 import android.content.res.Configuration; 20 import android.service.quicksettings.Tile; 21 import android.text.TextUtils; 22 import android.view.Gravity; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.ImageView; 27 import android.widget.TextView; 28 29 import com.android.settingslib.Utils; 30 import com.android.systemui.FontSizeUtils; 31 import com.android.systemui.R; 32 import com.android.systemui.plugins.qs.QSIconView; 33 import com.android.systemui.plugins.qs.QSTile; 34 35 import java.util.Objects; 36 37 /** View that represents a standard quick settings tile. **/ 38 public class QSTileView extends QSTileBaseView { 39 private static final int MAX_LABEL_LINES = 2; 40 private static final boolean DUAL_TARGET_ALLOWED = false; 41 private View mDivider; 42 protected TextView mLabel; 43 protected TextView mSecondLine; 44 private ImageView mPadLock; 45 private int mState; 46 private ViewGroup mLabelContainer; 47 private View mExpandIndicator; 48 private View mExpandSpace; 49 private ColorStateList mColorLabelDefault; 50 private ColorStateList mColorLabelUnavailable; 51 QSTileView(Context context, QSIconView icon)52 public QSTileView(Context context, QSIconView icon) { 53 this(context, icon, false); 54 } 55 QSTileView(Context context, QSIconView icon, boolean collapsedView)56 public QSTileView(Context context, QSIconView icon, boolean collapsedView) { 57 super(context, icon, collapsedView); 58 59 setClipChildren(false); 60 setClipToPadding(false); 61 62 setClickable(true); 63 setId(View.generateViewId()); 64 createLabel(); 65 setOrientation(VERTICAL); 66 setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); 67 mColorLabelDefault = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary); 68 // The text color for unavailable tiles is textColorSecondary, same as secondaryLabel for 69 // contrast purposes 70 mColorLabelUnavailable = Utils.getColorAttr(getContext(), 71 android.R.attr.textColorSecondary); 72 } 73 getLabel()74 TextView getLabel() { 75 return mLabel; 76 } 77 78 @Override onConfigurationChanged(Configuration newConfig)79 protected void onConfigurationChanged(Configuration newConfig) { 80 super.onConfigurationChanged(newConfig); 81 FontSizeUtils.updateFontSize(mLabel, R.dimen.qs_tile_text_size); 82 FontSizeUtils.updateFontSize(mSecondLine, R.dimen.qs_tile_text_size); 83 } 84 85 @Override getDetailY()86 public int getDetailY() { 87 return getTop() + mLabelContainer.getTop() + mLabelContainer.getHeight() / 2; 88 } 89 createLabel()90 protected void createLabel() { 91 mLabelContainer = (ViewGroup) LayoutInflater.from(getContext()) 92 .inflate(R.layout.qs_tile_label, this, false); 93 mLabelContainer.setClipChildren(false); 94 mLabelContainer.setClipToPadding(false); 95 mLabel = mLabelContainer.findViewById(R.id.tile_label); 96 mPadLock = mLabelContainer.findViewById(R.id.restricted_padlock); 97 mDivider = mLabelContainer.findViewById(R.id.underline); 98 mExpandIndicator = mLabelContainer.findViewById(R.id.expand_indicator); 99 mExpandSpace = mLabelContainer.findViewById(R.id.expand_space); 100 mSecondLine = mLabelContainer.findViewById(R.id.app_label); 101 addView(mLabelContainer); 102 } 103 104 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)105 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 106 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 107 108 // Remeasure view if the primary label requires more then 2 lines or the secondary label 109 // text will be cut off. 110 if (mLabel.getLineCount() > MAX_LABEL_LINES || !TextUtils.isEmpty(mSecondLine.getText()) 111 && mSecondLine.getLineHeight() > mSecondLine.getHeight()) { 112 mLabel.setSingleLine(); 113 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 114 } 115 } 116 117 @Override handleStateChanged(QSTile.State state)118 protected void handleStateChanged(QSTile.State state) { 119 super.handleStateChanged(state); 120 if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) { 121 mLabel.setTextColor(state.state == Tile.STATE_UNAVAILABLE ? mColorLabelUnavailable 122 : mColorLabelDefault); 123 mState = state.state; 124 mLabel.setText(state.label); 125 } 126 if (!Objects.equals(mSecondLine.getText(), state.secondaryLabel)) { 127 mSecondLine.setText(state.secondaryLabel); 128 mSecondLine.setVisibility(TextUtils.isEmpty(state.secondaryLabel) ? View.GONE 129 : View.VISIBLE); 130 } 131 boolean dualTarget = DUAL_TARGET_ALLOWED && state.dualTarget; 132 mExpandIndicator.setVisibility(dualTarget ? View.VISIBLE : View.GONE); 133 mExpandSpace.setVisibility(dualTarget ? View.VISIBLE : View.GONE); 134 mLabelContainer.setContentDescription(dualTarget ? state.dualLabelContentDescription 135 : null); 136 if (dualTarget != mLabelContainer.isClickable()) { 137 mLabelContainer.setClickable(dualTarget); 138 mLabelContainer.setLongClickable(dualTarget); 139 mLabelContainer.setBackground(dualTarget ? newTileBackground() : null); 140 } 141 mLabel.setEnabled(!state.disabledByPolicy); 142 mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE); 143 } 144 145 @Override init(OnClickListener click, OnClickListener secondaryClick, OnLongClickListener longClick)146 public void init(OnClickListener click, OnClickListener secondaryClick, 147 OnLongClickListener longClick) { 148 super.init(click, secondaryClick, longClick); 149 mLabelContainer.setOnClickListener(secondaryClick); 150 mLabelContainer.setOnLongClickListener(longClick); 151 mLabelContainer.setClickable(false); 152 mLabelContainer.setLongClickable(false); 153 } 154 } 155