Prototype tiles with side labels

This switches the tiles in QS to have the labels on the side, and
display in two columns.

Implemented:
* animation in expansion interleaves the tiles from QQS into QS, so the
first half of QQS moves to the left column
* Tapping on the label has the same effect as long pressing

Not implemented:
* animated shape between QQS and QS
* Edit screen

Landscape with media has a bug where scrolling pages resets to first
page. Also, animations in landscape with media don't look great.

To enable:
adb shell settings put secure sysui_side_labels 1
(0 to disable)

and restart SystemUI

Test: manual
Test: SystemUITests

Change-Id: I7468bc2c0b81e99a2de235a3b4312e678e968fd2
This commit is contained in:
Fabian Kozynski
2020-12-30 13:31:12 -05:00
parent 246e924066
commit 703f295c29
16 changed files with 345 additions and 41 deletions

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.systemui.qs.SideLabelTileLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tile_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false" />

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.systemui.qs.PagedTileLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/qs_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="true"
android:paddingBottom="@dimen/qs_paged_tile_layout_padding_bottom"
systemui:sideLabels="true" />

View File

@@ -34,7 +34,8 @@
<Space
android:id="@+id/expand_space"
android:layout_width="22dp"
android:layout_height="0dp" />
android:layout_height="0dp"
android:visibility="gone" />
<TextView
android:id="@+id/tile_label"

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="1px"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/textColorSecondary"
/>

View File

@@ -167,5 +167,9 @@
<attr name="android:drawable" />
<attr name="android:alpha" />
</declare-styleable>
<declare-styleable name="PagedTileLayout">
<attr name="sideLabels" format="boolean"/>
</declare-styleable>
</resources>

View File

@@ -519,6 +519,7 @@
Scaled @dimen/qs_page_indicator-width by .4f.
-->
<dimen name="qs_page_indicator_dot_width">6.4dp</dimen>
<dimen name="qs_tile_side_label_padding">6dp</dimen>
<dimen name="qs_tile_icon_size">24dp</dimen>
<dimen name="qs_tile_text_size">12sp</dimen>
<dimen name="qs_tile_divider_height">1dp</dimen>

View File

@@ -98,6 +98,7 @@ public class PageIndicator extends ViewGroup {
}
// Refresh state.
setIndex(mPosition >> 1);
requestLayout();
}
/**

View File

@@ -8,6 +8,7 @@ import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -47,7 +48,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
};
private final ArrayList<TileRecord> mTiles = new ArrayList<>();
private final ArrayList<TilePage> mPages = new ArrayList<>();
private final ArrayList<TileLayout> mPages = new ArrayList<>();
private PageIndicator mPageIndicator;
private float mPageIndicatorPosition;
@@ -71,6 +72,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
private int mMaxColumns = TileLayout.NO_MAX_COLUMNS;
private boolean mShowLabels = true;
private final boolean mSideLabels;
public PagedTileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -81,13 +83,18 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
mLayoutOrientation = getResources().getConfiguration().orientation;
mLayoutDirection = getLayoutDirection();
mClippingRect = new Rect();
TypedArray t = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.PagedTileLayout, 0, 0);
mSideLabels = t.getBoolean(R.styleable.PagedTileLayout_sideLabels, false);
t.recycle();
}
private int mLastMaxHeight = -1;
@Override
public void setShowLabels(boolean show) {
mShowLabels = show;
for (TilePage p : mPages) {
for (TileLayout p : mPages) {
p.setShowLabels(show);
}
mDistributeTiles = true;
@@ -145,7 +152,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
}
// This will dump to the ui log all the tiles that are visible in this page
private void logVisibleTiles(TilePage page) {
private void logVisibleTiles(TileLayout page) {
for (int i = 0; i < page.mRecords.size(); i++) {
QSTile t = page.mRecords.get(i).tile;
mUiEventLogger.logWithInstanceId(QSEvent.QS_TILE_VISIBLE, 0, t.getMetricsSpec(),
@@ -161,7 +168,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
}
private void updateListening() {
for (TilePage tilePage : mPages) {
for (TileLayout tilePage : mPages) {
tilePage.setListening(tilePage.getParent() != null && mListening);
}
}
@@ -222,13 +229,14 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mPages.add(createTilePage());
mPages.add(createTileLayout());
mAdapter.notifyDataSetChanged();
}
private TilePage createTilePage() {
TilePage page = (TilePage) LayoutInflater.from(getContext())
.inflate(R.layout.qs_paged_page, this, false);
private TileLayout createTileLayout() {
TileLayout page = (TileLayout) LayoutInflater.from(getContext())
.inflate(mSideLabels ? R.layout.qs_paged_page_side_labels
: R.layout.qs_paged_page, this, false);
page.setMinRows(mMinRows);
page.setMaxColumns(mMaxColumns);
page.setShowLabels(mShowLabels);
@@ -283,7 +291,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
int currentItem = getCurrentPageNumber();
for (int i = 0; i < mPages.size(); i++) {
TilePage page = mPages.get(i);
TileLayout page = mPages.get(i);
page.setSelected(i == currentItem ? selected : false);
if (page.isSelected()) {
logVisibleTiles(page);
@@ -325,7 +333,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
}
while (mPages.size() < numPages) {
if (DEBUG) Log.d(TAG, "Adding page");
mPages.add(createTilePage());
mPages.add(createTileLayout());
}
while (mPages.size() > numPages) {
if (DEBUG) Log.d(TAG, "Removing page");
@@ -422,7 +430,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
final int nRows = mPages.get(0).mRows;
for (int i = 0; i < mPages.size(); i++) {
TilePage t = mPages.get(i);
TileLayout t = mPages.get(i);
t.mRows = nRows;
}
}
@@ -465,19 +473,19 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
public int getNumVisibleTiles() {
if (mPages.size() == 0) return 0;
TilePage currentPage = mPages.get(getCurrentPageNumber());
TileLayout currentPage = mPages.get(getCurrentPageNumber());
return currentPage.mRecords.size();
}
public void startTileReveal(Set<String> tileSpecs, final Runnable postAnimation) {
if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0 || !beginFakeDrag()) {
// Do not start the reveal animation unless there are tiles to animate, multiple
// TilePages available and the user has not already started dragging.
// TileLayouts available and the user has not already started dragging.
return;
}
final int lastPageNumber = mPages.size() - 1;
final TilePage lastPage = mPages.get(lastPageNumber);
final TileLayout lastPage = mPages.get(lastPageNumber);
final ArrayList<Animator> bounceAnims = new ArrayList<>();
for (TileRecord tr : lastPage.mRecords) {
if (tileSpecs.contains(tr.tile.getTileSpec())) {
@@ -557,12 +565,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
return mRecords.size() >= maxTiles();
}
public int maxTiles() {
// Each page should be able to hold at least one tile. If there's not enough room to
// show even 1 or there are no tiles, it probably means we are in the middle of setting
// up.
return Math.max(mColumns * mRows, 1);
}
}
private final PagerAdapter mAdapter = new PagerAdapter() {

View File

@@ -26,6 +26,7 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.Gravity;
@@ -112,6 +113,7 @@ public class QSPanel extends LinearLayout implements Tunable {
private int mMediaTotalBottomMargin;
private int mFooterMarginStartHorizontal;
private Consumer<Boolean> mMediaVisibilityChangedListener;
private final boolean mSideLabels;
public QSPanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -119,6 +121,8 @@ public class QSPanel extends LinearLayout implements Tunable {
mMediaTotalBottomMargin = getResources().getDimensionPixelSize(
R.dimen.quick_settings_bottom_margin_media);
mContext = context;
mSideLabels = Settings.Secure.getInt(
mContext.getContentResolver(), "sysui_side_labels", 0) != 0;
setOrientation(VERTICAL);
@@ -174,8 +178,9 @@ public class QSPanel extends LinearLayout implements Tunable {
/** */
public QSTileLayout createRegularTileLayout() {
if (mRegularTileLayout == null) {
mRegularTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
R.layout.qs_paged_tile_layout, this, false);
mRegularTileLayout = (QSTileLayout) LayoutInflater.from(mContext)
.inflate(mSideLabels ? R.layout.qs_paged_tile_layout_side_labels
: R.layout.qs_paged_tile_layout, this, false);
}
return mRegularTileLayout;
}
@@ -748,7 +753,13 @@ public class QSPanel extends LinearLayout implements Tunable {
if (needsDynamicRowsAndColumns()) {
newLayout.setMinRows(horizontal ? 2 : 1);
// Let's use 3 columns to match the current layout
newLayout.setMaxColumns(horizontal ? 3 : TileLayout.NO_MAX_COLUMNS);
int columns;
if (mSideLabels) {
columns = horizontal ? 1 : 2;
} else {
columns = horizontal ? 3 : TileLayout.NO_MAX_COLUMNS;
}
newLayout.setMaxColumns(columns);
}
updateMargins(mediaHostView);
}
@@ -763,6 +774,10 @@ public class QSPanel extends LinearLayout implements Tunable {
updatePadding();
}
boolean useSideLabels() {
return mSideLabels;
}
private class H extends Handler {
private static final int SHOW_DETAIL = 1;
private static final int SET_TILE_VISIBILITY = 2;

View File

@@ -90,14 +90,26 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
@Override
public void setTiles() {
List<QSTile> tiles = new ArrayList();
List<QSTile> tiles = new ArrayList<>();
for (QSTile tile : mHost.getTiles()) {
tiles.add(tile);
if (tiles.size() == mView.getNumQuickTiles()) {
break;
}
}
super.setTiles(tiles, true);
if (mView.useSideLabels()) {
List<QSTile> newTiles = new ArrayList<>();
for (int i = 0; i < tiles.size(); i += 2) {
newTiles.add(tiles.get(i));
}
for (int i = 1; i < tiles.size(); i += 2) {
newTiles.add(tiles.get(i));
}
super.setTiles(newTiles, true);
} else {
super.setTiles(tiles, true);
}
}
/** */

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.qs
import android.content.Context
import android.util.AttributeSet
import com.android.systemui.R
open class SideLabelTileLayout(context: Context, attrs: AttributeSet) : TileLayout(context, attrs) {
override fun updateResources(): Boolean {
return super.updateResources().also {
mResourceColumns = 2
mMaxAllowedRows = 4
mCellMarginHorizontal = (mCellMarginHorizontal * 1.2).toInt()
mCellMarginVertical = mCellMarginHorizontal
mMaxCellHeight = context.resources.getDimensionPixelSize(R.dimen.qs_quick_tile_size)
}
}
override fun setShowLabels(show: Boolean) { }
override fun isFull(): Boolean {
return mRecords.size >= maxTiles()
}
}

View File

@@ -42,7 +42,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
private final boolean mLessRows;
private int mMinRows = 1;
private int mMaxColumns = NO_MAX_COLUMNS;
private int mResourceColumns;
protected int mResourceColumns;
public TileLayout(Context context) {
this(context, null);
@@ -216,7 +216,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
private int getCellHeight() {
protected int getCellHeight() {
return mShowLabels ? mMaxCellHeight : mMaxCellHeight / 2;
}
@@ -260,4 +260,18 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
public int getNumVisibleTiles() {
return mRecords.size();
}
public boolean isFull() {
return false;
}
/**
* @return The maximum number of tiles this layout can hold
*/
public int maxTiles() {
// Each layout should be able to hold at least one tile. If there's not enough room to
// show even 1 or there are no tiles, it probably means we are in the middle of setting
// up.
return Math.max(mColumns * mRows, 1);
}
}

View File

@@ -48,6 +48,7 @@ import com.android.systemui.qs.tiles.UserTile;
import com.android.systemui.qs.tiles.WifiTile;
import com.android.systemui.qs.tiles.WorkModeTile;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.util.settings.SecureSettings;
import javax.inject.Inject;
import javax.inject.Provider;
@@ -84,9 +85,12 @@ public class QSFactoryImpl implements QSFactory {
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
private final boolean mSideLabels;
@Inject
public QSFactoryImpl(
Lazy<QSHost> qsHostLazy,
SecureSettings settings,
Provider<CustomTile.Builder> customTileBuilderProvider,
Provider<WifiTile> wifiTileProvider,
Provider<BluetoothTile> bluetoothTileProvider,
@@ -112,6 +116,8 @@ public class QSFactoryImpl implements QSFactory {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
mSideLabels = settings.getInt("sysui_side_labels", 0) != 0;
mWifiTileProvider = wifiTileProvider;
mBluetoothTileProvider = bluetoothTileProvider;
mCellularTileProvider = cellularTileProvider;
@@ -212,6 +218,8 @@ public class QSFactoryImpl implements QSFactory {
QSIconView icon = tile.createTileView(context);
if (collapsedView) {
return new QSTileBaseView(context, icon, collapsedView);
} else if (mSideLabels) {
return new QSTileViewHorizontal(context, icon);
} else {
return new com.android.systemui.qs.tileimpl.QSTileView(context, icon);
}

View File

@@ -61,15 +61,15 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
private final FrameLayout mIconFrame;
protected QSIconView mIcon;
protected RippleDrawable mRipple;
private Drawable mTileBackground;
protected Drawable mTileBackground;
private String mAccessibilityClass;
private boolean mTileState;
private boolean mCollapsedView;
private boolean mShowRippleEffect = true;
protected boolean mShowRippleEffect = true;
private float mStrokeWidthActive;
private float mStrokeWidthInactive;
private final ImageView mBg;
protected final ImageView mBg;
private final int mColorActive;
private final int mColorInactive;
private final int mColorDisabled;
@@ -162,7 +162,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
}
}
private void updateRippleSize() {
protected void updateRippleSize() {
// center the touch feedback on the center of the icon, and dial it down a bit
final int cx = mIconFrame.getMeasuredWidth() / 2 + mIconFrame.getLeft();
final int cy = mIconFrame.getMeasuredHeight() / 2 + mIconFrame.getTop();
@@ -311,7 +311,7 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
return mLocInScreen[1] >= -getHeight();
}
private int getCircleColor(int state) {
protected int getCircleColor(int state) {
switch (state) {
case Tile.STATE_ACTIVE:
return mColorActive;

View File

@@ -37,7 +37,6 @@ import java.util.Objects;
/** View that represents a standard quick settings tile. **/
public class QSTileView extends QSTileBaseView {
private static final int MAX_LABEL_LINES = 2;
private static final boolean DUAL_TARGET_ALLOWED = false;
private View mDivider;
protected TextView mLabel;
protected TextView mSecondLine;
@@ -46,8 +45,10 @@ public class QSTileView extends QSTileBaseView {
protected ViewGroup mLabelContainer;
private View mExpandIndicator;
private View mExpandSpace;
private ColorStateList mColorLabelDefault;
protected ColorStateList mColorLabelActive;
protected ColorStateList mColorLabelInactive;
private ColorStateList mColorLabelUnavailable;
protected boolean mDualTargetAllowed = false;
public QSTileView(Context context, QSIconView icon) {
this(context, icon, false);
@@ -64,7 +65,8 @@ public class QSTileView extends QSTileBaseView {
createLabel();
setOrientation(VERTICAL);
setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
mColorLabelDefault = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary);
mColorLabelActive = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary);
mColorLabelInactive = mColorLabelActive;
// The text color for unavailable tiles is textColorSecondary, same as secondaryLabel for
// contrast purposes
mColorLabelUnavailable = Utils.getColorAttr(getContext(),
@@ -118,8 +120,15 @@ public class QSTileView extends QSTileBaseView {
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) {
mLabel.setTextColor(state.state == Tile.STATE_UNAVAILABLE ? mColorLabelUnavailable
: mColorLabelDefault);
ColorStateList labelColor;
if (state.state == Tile.STATE_ACTIVE) {
labelColor = mColorLabelActive;
} else if (state.state == Tile.STATE_INACTIVE) {
labelColor = mColorLabelInactive;
} else {
labelColor = mColorLabelUnavailable;
}
mLabel.setTextColor(labelColor);
mState = state.state;
mLabel.setText(state.label);
}
@@ -128,9 +137,8 @@ public class QSTileView extends QSTileBaseView {
mSecondLine.setVisibility(TextUtils.isEmpty(state.secondaryLabel) ? View.GONE
: View.VISIBLE);
}
boolean dualTarget = DUAL_TARGET_ALLOWED && state.dualTarget;
mExpandIndicator.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
mExpandSpace.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
boolean dualTarget = mDualTargetAllowed && state.dualTarget;
handleExpand(dualTarget);
mLabelContainer.setContentDescription(dualTarget ? state.dualLabelContentDescription
: null);
if (dualTarget != mLabelContainer.isClickable()) {
@@ -142,6 +150,11 @@ public class QSTileView extends QSTileBaseView {
mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
}
protected void handleExpand(boolean dualTarget) {
mExpandIndicator.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
mExpandSpace.setVisibility(dualTarget ? View.VISIBLE : View.GONE);
}
@Override
public void init(OnClickListener click, OnClickListener secondaryClick,
OnLongClickListener longClick) {

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.qs.tileimpl
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.PaintDrawable
import android.graphics.drawable.RippleDrawable
import android.service.quicksettings.Tile.STATE_ACTIVE
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import com.android.systemui.R
import com.android.systemui.plugins.qs.QSIconView
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState
class QSTileViewHorizontal(
context: Context,
icon: QSIconView
) : QSTileView(context, icon, false) {
private var paintDrawable: PaintDrawable? = null
private var divider: View? = null
init {
orientation = HORIZONTAL
mDualTargetAllowed = true
mBg.setImageDrawable(null)
createDivider()
mColorLabelActive = ColorStateList.valueOf(getColorForState(getContext(), STATE_ACTIVE))
}
override fun createLabel() {
super.createLabel()
findViewById<LinearLayout>(R.id.label_group)?.gravity = Gravity.START
mLabel.gravity = Gravity.START
mSecondLine.gravity = Gravity.START
val padding = context.resources.getDimensionPixelSize(R.dimen.qs_tile_side_label_padding)
mLabelContainer.setPadding(padding, padding, padding, padding)
(mLabelContainer.layoutParams as LayoutParams).gravity = Gravity.CENTER_VERTICAL
}
fun createDivider() {
divider = LayoutInflater.from(context).inflate(R.layout.qs_tile_label_divider, this, false)
val position = indexOfChild(mLabelContainer)
addView(divider, position)
}
override fun init(
click: OnClickListener?,
secondaryClick: OnClickListener?,
longClick: OnLongClickListener?
) {
super.init(click, secondaryClick, longClick)
mLabelContainer.setOnClickListener {
longClick?.onLongClick(it)
}
mLabelContainer.isClickable = false
}
override fun updateRippleSize() {
}
override fun newTileBackground(): Drawable? {
val d = super.newTileBackground()
if (paintDrawable == null) {
paintDrawable = PaintDrawable(Color.WHITE).apply {
setCornerRadius(30f)
}
}
if (d is RippleDrawable) {
d.addLayer(paintDrawable)
return d
} else {
return paintDrawable
}
}
override fun setClickable(clickable: Boolean) {
super.setClickable(clickable)
background = mTileBackground
if (clickable && mShowRippleEffect) {
mRipple?.setHotspotBounds(left, top, right, bottom)
} else {
mRipple?.setHotspotBounds(0, 0, 0, 0)
}
}
override fun handleStateChanged(state: QSTile.State) {
super.handleStateChanged(state)
paintDrawable?.setTint(getCircleColor(state.state))
mSecondLine.setTextColor(mLabel.textColors)
mLabelContainer.background = null
divider?.backgroundTintList = mLabel.textColors
}
override fun handleExpand(dualTarget: Boolean) {}
}