diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java index ca13204487263..2213d1c5c8449 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java @@ -46,6 +46,15 @@ public abstract class QSTileView extends LinearLayout { * background circle/peripherals. To retrieve only the inner icon, use {@link #getIcon()}. */ public abstract View getIconWithBackground(); + + /** + * Returns the {@link View} containing the icon on the right + * + * @see com.android.systemui.qs.tileimpl.QSTileViewHorizontal#sideView + */ + public View getSecondaryIcon() { + return null; + } public abstract void init(QSTile tile); public abstract void onStateChanged(State state); @@ -54,4 +63,8 @@ public abstract class QSTileView extends LinearLayout { public View getLabelContainer() { return null; } + + public View getSecondaryLabel() { + return null; + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index 294d76590fed7..488ada97aa421 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -80,7 +80,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private QSExpansionPathInterpolator mQSExpansionPathInterpolator; private TouchAnimator mFirstPageAnimator; private TouchAnimator mFirstPageDelayedAnimator; - private TouchAnimator mTranslationXAnimator; private TouchAnimator mTranslationYAnimator; private TouchAnimator mNonfirstPageAnimator; private TouchAnimator mNonfirstPageDelayedAnimator; @@ -219,10 +218,29 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mOnFirstPage = isFirst; } + private void translateContent( + View qqsView, + View qsView, + View commonParent, + int yOffset, + int[] temp, + TouchAnimator.Builder animatorBuilder + ) { + getRelativePosition(temp, qqsView, commonParent); + int qqsPos = temp[1]; + getRelativePosition(temp, qsView, commonParent); + int qsPos = temp[1]; + + int diff = qsPos - qqsPos - yOffset; + animatorBuilder.addFloat(qqsView, "translationY", 0, diff); + animatorBuilder.addFloat(qsView, "translationY", -diff, 0); + mAllViews.add(qqsView); + mAllViews.add(qsView); + } + private void updateAnimators() { mNeedsAnimatorUpdate = false; TouchAnimator.Builder firstPageBuilder = new Builder(); - TouchAnimator.Builder translationXBuilder = new Builder(); TouchAnimator.Builder translationYBuilder = new Builder(); Collection tiles = mHost.getTiles(); @@ -241,7 +259,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha QSTileLayout tileLayout = mQsPanelController.getTileLayout(); mAllViews.add((View) tileLayout); int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; - int width = mQs.getView() != null ? mQs.getView().getMeasuredWidth() : 0; int heightDiff = height - mQs.getHeader().getBottom() + mQs.getHeader().getPaddingBottom(); if (!mTranslateWhileExpanding) { @@ -268,68 +285,62 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha QSTileView quickTileView = mQuickQSPanelController.getTileView(tile); if (quickTileView == null) continue; - getRelativePosition(loc1, quickTileView.getIcon().getIconView(), view); - getRelativePosition(loc2, tileIcon, view); - final int xDiff = loc2[0] - loc1[0]; - int yDiff = loc2[1] - loc1[1]; + getRelativePosition(loc1, quickTileView, view); + getRelativePosition(loc2, tileView, view); + int yOffset = loc2[1] - loc1[1]; - if (count < tileLayout.getNumVisibleTiles()) { - getRelativePosition(loc1, quickTileView, view); - getRelativePosition(loc2, tileView, view); - int yOffset = loc2[1] - loc1[1]; - // Move the quick tile right from its location to the new one. - View v = quickTileView.getIcon(); - translationXBuilder.addFloat(v, "translationX", 0, xDiff); - translationYBuilder.addFloat(v, "translationY", 0, yDiff - yOffset); - mAllViews.add(v); + // Offset the translation animation on the views + // (that goes from 0 to getOffsetTranslation) + int offsetWithQSBHTranslation = + yOffset - mQuickStatusBarHeader.getOffsetTranslation(); + translationYBuilder.addFloat(quickTileView, "translationY", 0, + offsetWithQSBHTranslation); + translationYBuilder.addFloat(tileView, "translationY", + -offsetWithQSBHTranslation, 0); - // Move the real tile from the quick tile position to its final - // location. - v = tileIcon; - translationXBuilder.addFloat(v, "translationX", -xDiff, 0); - translationYBuilder.addFloat(v, "translationY", -yDiff + yOffset, 0); - - // Offset the translation animation on the views - // (that goes from 0 to getOffsetTranslation) - int offsetWithQSBHTranslation = - yOffset - mQuickStatusBarHeader.getOffsetTranslation(); - translationYBuilder.addFloat(quickTileView, "translationY", 0, - offsetWithQSBHTranslation); - translationYBuilder.addFloat(tileView, "translationY", - -offsetWithQSBHTranslation, 0); - - if (mQQSTileHeightAnimator == null) { - mQQSTileHeightAnimator = new HeightExpansionAnimator(this, - quickTileView.getHeight(), tileView.getHeight()); - qqsTileHeight = quickTileView.getHeight(); - } - - mQQSTileHeightAnimator.addView(quickTileView); - View qqsLabelContainer = quickTileView.getLabelContainer(); - View qsLabelContainer = tileView.getLabelContainer(); - - getRelativePosition(loc1, qqsLabelContainer, view); - getRelativePosition(loc2, qsLabelContainer, view); - yDiff = loc2[1] - loc1[1] - yOffset; - - translationYBuilder.addFloat(qqsLabelContainer, "translationY", 0, yDiff); - translationYBuilder.addFloat(qsLabelContainer, "translationY", -yDiff, 0); - mAllViews.add(qqsLabelContainer); - mAllViews.add(qsLabelContainer); - } else { // These tiles disappear when expanding - firstPageBuilder.addFloat(quickTileView, "alpha", 1, 0); - translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); - - // xDiff is negative here and this makes it "more" negative - final int translationX = - mQsPanelController.isLayoutRtl() ? xDiff - width : xDiff + width; - translationXBuilder.addFloat(quickTileView, "translationX", 0, - translationX); + if (mQQSTileHeightAnimator == null) { + mQQSTileHeightAnimator = new HeightExpansionAnimator(this, + quickTileView.getHeight(), tileView.getHeight()); + qqsTileHeight = quickTileView.getHeight(); } + mQQSTileHeightAnimator.addView(quickTileView); + + // Icons + translateContent( + quickTileView.getIcon(), + tileView.getIcon(), + view, + yOffset, + loc1, + translationYBuilder + ); + + // Label containers + translateContent( + quickTileView.getLabelContainer(), + tileView.getLabelContainer(), + view, + yOffset, + loc1, + translationYBuilder + ); + + // Secondary icon + translateContent( + quickTileView.getSecondaryIcon(), + tileView.getSecondaryIcon(), + view, + yOffset, + loc1, + translationYBuilder + ); + + firstPageBuilder.addFloat(quickTileView.getSecondaryLabel(), "alpha", 0, 1); + mQuickQsViews.add(tileView); - mAllViews.add(tileView.getIcon()); mAllViews.add(quickTileView); + mAllViews.add(quickTileView.getSecondaryLabel()); } else if (mFullRows && isIconInAnimatedRow(count)) { firstPageBuilder.addFloat(tileView, "translationY", -heightDiff, 0); @@ -391,17 +402,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha if (mQsPanelController.getDivider() != null) { mAllViews.add(mQsPanelController.getDivider()); } - - float px = 0; - if (tiles.size() <= 3) { - px = 1; - } else if (tiles.size() <= 6) { - px = .4f; - } - mQSExpansionPathInterpolator.setControlX2(px); - translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator()); translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator()); - mTranslationXAnimator = translationXBuilder.build(); mTranslationYAnimator = translationYBuilder.build(); if (mQQSTileHeightAnimator != null) { mQQSTileHeightAnimator.setInterpolator( @@ -474,7 +475,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQuickQsPanel.setAlpha(1); mFirstPageAnimator.setPosition(position); mFirstPageDelayedAnimator.setPosition(position); - mTranslationXAnimator.setPosition(position); mTranslationYAnimator.setPosition(position); if (mBrightnessAnimator != null) { mBrightnessAnimator.setPosition(position); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/ButtonRelativeLayout.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/ButtonRelativeLayout.java index 2c17b874dcab6..962537a01fe20 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/ButtonRelativeLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/ButtonRelativeLayout.java @@ -16,11 +16,17 @@ package com.android.systemui.qs.tileimpl; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.Button; import android.widget.RelativeLayout; +/** + * Used for QS tile labels + */ public class ButtonRelativeLayout extends RelativeLayout { + private View mIgnoredView; + public ButtonRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } @@ -29,4 +35,27 @@ public class ButtonRelativeLayout extends RelativeLayout { public CharSequence getAccessibilityClassName() { return Button.class.getName(); } + + /** + * Set a view to be ignored for measure. + * + * The view will be measured and laid out, but its size will be subtracted from the total size + * of this view. It assumes that this view only contributes vertical height. + */ + public void setIgnoredView(View view) { + if (mIgnoredView == null || mIgnoredView.getParent() == this) { + mIgnoredView = view; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mIgnoredView != null && mIgnoredView.getVisibility() != GONE) { + int height = mIgnoredView.getMeasuredHeight(); + MarginLayoutParams lp = (MarginLayoutParams) mIgnoredView.getLayoutParams(); + height = height - lp.bottomMargin - lp.topMargin; + setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() - height); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java index 3d5a709a5fddd..50417e9ab2592 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java @@ -22,7 +22,6 @@ import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; @@ -44,7 +43,7 @@ public class QSTileView extends QSTileBaseView { protected TextView mSecondLine; private ImageView mPadLock; protected int mState; - protected ViewGroup mLabelContainer; + protected ButtonRelativeLayout mLabelContainer; private View mExpandIndicator; private View mExpandSpace; protected ColorStateList mColorLabelActive; @@ -92,7 +91,7 @@ public class QSTileView extends QSTileBaseView { } protected void createLabel() { - mLabelContainer = (ViewGroup) LayoutInflater.from(getContext()) + mLabelContainer = (ButtonRelativeLayout) LayoutInflater.from(getContext()) .inflate(R.layout.qs_tile_label, this, false); mLabelContainer.setClipChildren(false); mLabelContainer.setClipToPadding(false); @@ -140,7 +139,7 @@ public class QSTileView extends QSTileBaseView { } if (!Objects.equals(mSecondLine.getText(), state.secondaryLabel)) { mSecondLine.setText(state.secondaryLabel); - mSecondLine.setVisibility(TextUtils.isEmpty(state.secondaryLabel) || mCollapsedView + mSecondLine.setVisibility(TextUtils.isEmpty(state.secondaryLabel) ? View.GONE : View.VISIBLE); } boolean dualTarget = mDualTargetAllowed && state.dualTarget; @@ -193,4 +192,9 @@ public class QSTileView extends QSTileBaseView { public View getLabelContainer() { return mLabelContainer; } + + @Override + public View getSecondaryLabel() { + return mSecondLine; + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt index b9533237e3d5d..70d51ee1c516b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt @@ -25,6 +25,7 @@ import android.graphics.drawable.RippleDrawable import android.service.quicksettings.Tile.STATE_ACTIVE import android.view.Gravity import android.view.View +import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.widget.ImageView import android.widget.LinearLayout import android.widget.RelativeLayout @@ -43,7 +44,7 @@ open class QSTileViewHorizontal( private var paintColor = Color.WHITE private var paintAnimator: ValueAnimator? = null private var labelAnimator: ValueAnimator? = null - private var mSideView: ImageView = ImageView(mContext) + private var sideView: ImageView = ImageView(mContext) override var heightOverride: Int = HeightOverrideable.NO_OVERRIDE init { @@ -59,13 +60,14 @@ open class QSTileViewHorizontal( val iconSize = context.resources.getDimensionPixelSize(R.dimen.qs_icon_size) addView(mIcon, 0, LayoutParams(iconSize, iconSize)) - mSideView.visibility = View.GONE - addView( - mSideView, - -1, - LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply { - gravity = Gravity.CENTER_VERTICAL - }) + sideView.visibility = View.GONE + val sideViewLayoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { + gravity = Gravity.CENTER_VERTICAL + marginStart = context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin) + } + addView(sideView, -1, sideViewLayoutParams) + sideView.adjustViewBounds = true + sideView.scaleType = ImageView.ScaleType.FIT_CENTER mColorLabelActive = ColorStateList.valueOf(getColorForState(getContext(), STATE_ACTIVE)) changeLabelColor(getLabelColor(mState)) // Matches the default state of the tile @@ -89,16 +91,17 @@ open class QSTileViewHorizontal( mLabelContainer.setPadding(0, 0, 0, 0) (mLabelContainer.layoutParams as MarginLayoutParams).apply { marginStart = context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin) + marginEnd = 0 + gravity = Gravity.CENTER_VERTICAL or Gravity.START } mLabel.gravity = Gravity.START mLabel.textDirection = TEXT_DIRECTION_LOCALE mSecondLine.gravity = Gravity.START mSecondLine.textDirection = TEXT_DIRECTION_LOCALE - (mLabelContainer.layoutParams as LayoutParams).gravity = - Gravity.CENTER_VERTICAL or Gravity.START if (mCollapsedView) { - mSecondLine.visibility = GONE + mSecondLine.alpha = 0f + mLabelContainer.setIgnoredView(mSecondLine) } } @@ -183,9 +186,7 @@ open class QSTileViewHorizontal( private fun setLabelsColor(color: ColorStateList) { mLabel.setTextColor(color) - if (!mCollapsedView) { - mSecondLine.setTextColor(color) - } + mSecondLine.setTextColor(color) } private fun clearBackgroundAnimator() { @@ -198,19 +199,17 @@ open class QSTileViewHorizontal( private fun loadSideViewDrawableIfNecessary(state: QSTile.State) { if (state.sideViewDrawable != null) { - (mSideView.layoutParams as MarginLayoutParams).apply { - marginStart = - context.resources.getDimensionPixelSize(R.dimen.qs_label_container_margin) - } - mSideView.setImageDrawable(state.sideViewDrawable) - mSideView.visibility = View.VISIBLE - mSideView.adjustViewBounds = true - mSideView.scaleType = ImageView.ScaleType.FIT_CENTER + sideView.setImageDrawable(state.sideViewDrawable) + sideView.visibility = View.VISIBLE } else { - mSideView.setImageDrawable(null) - mSideView.visibility = GONE + sideView.setImageDrawable(null) + sideView.visibility = GONE } } override fun handleExpand(dualTarget: Boolean) {} + + override fun getSecondaryIcon(): View { + return sideView + } } \ No newline at end of file