Merge "Refactored layout of QQS and transition animation."
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index f1b7eec..ca1b489 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -261,6 +261,12 @@
return mPages.get(0).mColumns;
}
+ public int getNumVisibleTiles() {
+ if (mPages.size() == 0) return 0;
+ TilePage currentPage = mPages.get(getCurrentItem());
+ 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
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 2a4bb60..3744d7d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -155,6 +155,7 @@
TouchAnimator.Builder translationYBuilder = new Builder();
if (mQsPanel.getHost() == null) return;
+ if (mQuickQsPanel.getTileLayout().getNumVisibleTiles() < 1) return;
Collection<QSTile> tiles = mQsPanel.getHost().getTiles();
int count = 0;
int[] loc1 = new int[2];
@@ -169,6 +170,7 @@
QSTileLayout tileLayout = mQsPanel.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();
firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0);
@@ -181,7 +183,9 @@
}
final View tileIcon = tileView.getIcon().getIconView();
View view = mQs.getView();
- if (count < mNumQuickTiles && mAllowFancy) {
+
+ // This case: less tiles to animate in small displays.
+ if (count < mQuickQsPanel.getTileLayout().getNumVisibleTiles() && mAllowFancy) {
// Quick tiles.
QSTileView quickTileView = mQuickQsPanel.getTileView(tile);
if (quickTileView == null) continue;
@@ -192,18 +196,26 @@
final int xDiff = loc2[0] - loc1[0];
final int yDiff = loc2[1] - loc1[1];
lastXDiff = loc1[0] - lastX;
- // Move the quick tile right from its location to the new one.
- translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff);
- translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
- // Counteract the parent translation on the tile. So we have a static base to
- // animate the label position off from.
- //firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0);
+ if (count < tileLayout.getNumVisibleTiles()) {
+ // Move the quick tile right from its location to the new one.
+ translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff);
+ translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
- // Move the real tile from the quick tile position to its final
- // location.
- translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0);
- translationYBuilder.addFloat(tileView, "translationY", -yDiff, 0);
+ // Counteract the parent translation on the tile. So we have a static base to
+ // animate the label position off from.
+ //firstPageBuilder.addFloat(tileView, "translationY", mQsPanel.getHeight(), 0);
+
+ // Move the real tile from the quick tile position to its final
+ // location.
+ translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0);
+ translationYBuilder.addFloat(tileView, "translationY", -yDiff, 0);
+
+ } else { // These tiles disappear when expanding
+ firstPageBuilder.addFloat(quickTileView, "alpha", 1, 0);
+ translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
+ translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff + width);
+ }
mQuickQsViews.add(tileView.getIconWithBackground());
mAllViews.add(tileView.getIcon());
@@ -218,10 +230,9 @@
final int xDiff = loc2[0] - loc1[0];
final int yDiff = loc2[1] - loc1[1];
- firstPageBuilder.addFloat(tileView, "translationY", heightDiff, 0);
- translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0);
+ firstPageBuilder.addFloat(tileView, "translationY", -heightDiff, 0);
translationYBuilder.addFloat(tileView, "translationY", -yDiff, 0);
- translationYBuilder.addFloat(tileIcon, "translationY", -yDiff, 0);
+ translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0);
mAllViews.add(tileIcon);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 3fc258b..6c330b0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -663,5 +663,7 @@
void setListening(boolean listening);
default void setExpansion(float expansion) {}
+
+ int getNumVisibleTiles();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 1c50f79..556786a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -18,18 +18,17 @@
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
-import android.widget.Space;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
import com.android.systemui.plugins.qs.QSTile.State;
-import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -43,6 +42,7 @@
public class QuickQSPanel extends QSPanel {
public static final String NUM_QUICK_TILES = "sysui_qqs_count";
+ private static final String TAG = "QuickQSPanel";
private boolean mDisabledByPolicy;
private static int mDefaultMaxTiles;
@@ -178,121 +178,95 @@
super.setVisibility(visibility);
}
- private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
+ private static class HeaderTileLayout extends TileLayout {
- protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
private boolean mListening;
- /** Size of the QS tile (width & height). */
- private int mTileDimensionSize;
public HeaderTileLayout(Context context) {
super(context);
setClipChildren(false);
setClipToPadding(false);
-
- mTileDimensionSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.qs_quick_tile_size);
- updateLayoutParams();
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- updateLayoutParams();
+ updateResources();
+ }
+
+ @Override
+ public void onFinishInflate(){
+ updateResources();
}
private void updateLayoutParams() {
- setGravity(Gravity.CENTER);
int width = getResources().getDimensionPixelSize(R.dimen.qs_quick_layout_width);
- LayoutParams lp = new LayoutParams(width, LayoutParams.MATCH_PARENT);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width, LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.CENTER_HORIZONTAL;
setLayoutParams(lp);
}
- /**
- * Returns {@link LayoutParams} based on the given {@code spaceWidth}. If the width is 0,
- * then we're going to have the space expand to take up as much space as possible. If the
- * width is non-zero, we want the inter-tile spacers to be fixed.
- */
- private LayoutParams generateSpaceLayoutParams() {
- LayoutParams lp = new LayoutParams(0, mTileDimensionSize);
- lp.weight = 1;
- lp.gravity = Gravity.CENTER;
- return lp;
- }
-
- @Override
- public void setListening(boolean listening) {
- if (mListening == listening) return;
- mListening = listening;
- for (TileRecord record : mRecords) {
- record.tile.setListening(this, mListening);
- }
- }
-
- @Override
- public void addTile(TileRecord tile) {
- if (getChildCount() != 0) {
- addView(new Space(mContext), getChildCount(), generateSpaceLayoutParams());
- }
-
- addView(tile.tileView, getChildCount(), generateTileLayoutParams());
- mRecords.add(tile);
- tile.tile.setListening(this, mListening);
- }
-
private LayoutParams generateTileLayoutParams() {
- LayoutParams lp = new LayoutParams(mTileDimensionSize, mTileDimensionSize);
- lp.gravity = Gravity.CENTER;
+ LayoutParams lp = new LayoutParams(mCellWidth, mCellHeight);
return lp;
}
@Override
- public void removeTile(TileRecord tile) {
- int childIndex = getChildIndex(tile.tileView);
- // Remove the tile.
- removeViewAt(childIndex);
- if (getChildCount() != 0) {
- // Remove its spacer as well.
- removeViewAt(childIndex);
- }
- mRecords.remove(tile);
- tile.tile.setListening(this, false);
- }
-
- private int getChildIndex(QSTileView tileView) {
- final int childViewCount = getChildCount();
- for (int i = 0; i < childViewCount; i++) {
- if (getChildAt(i) == tileView) {
- return i;
- }
- }
- return -1;
+ protected void addTileView(TileRecord tile) {
+ addView(tile.tileView, getChildCount(), generateTileLayoutParams());
}
@Override
- public int getOffsetTop(TileRecord tile) {
- return 0;
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ // We only care about clipping on the right side
+ Rect bounds = new Rect(0, 0, r - l, 10000);
+ setClipBounds(bounds);
+
+ calculateColumns();
+
+ for (int i = 0; i < mRecords.size(); i++) {
+ mRecords.get(i).tileView.setVisibility( i < mColumns ? View.VISIBLE : View.GONE);
+ }
+
+ setAccessibilityOrder();
+ layoutTileRecords(mColumns);
}
@Override
public boolean updateResources() {
- // No resources here.
+ mCellWidth = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
+ mCellHeight = mCellWidth;
+
+ updateLayoutParams();
+
return false;
}
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
+ private boolean calculateColumns() {
+ int prevNumColumns = mColumns;
+ int maxTiles = mRecords.size();
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (hideOverflowingChildren(widthMeasureSpec)) {
- return; // Rely on visibility change to trigger remeasure.
+ if (maxTiles == 0){ // Early return during setup
+ mColumns = 0;
+ return true;
}
+ final int availableWidth = getMeasuredWidth() - getPaddingStart() - getPaddingEnd();
+ final int leftoverWithespace = availableWidth - maxTiles * mCellWidth;
+ final int smallestHorizontalMarginNeeded = leftoverWithespace / (maxTiles - 1);
+
+ if (smallestHorizontalMarginNeeded > 0){
+ mCellMarginHorizontal = smallestHorizontalMarginNeeded;
+ mColumns = maxTiles;
+ } else{
+ mColumns = mCellWidth == 0 ? 1 :
+ Math.min(maxTiles, availableWidth / mCellWidth );
+ mCellMarginHorizontal = (availableWidth - mColumns * mCellWidth) / (mColumns - 1);
+ }
+ return mColumns != prevNumColumns;
+ }
+
+ private void setAccessibilityOrder() {
if (mRecords != null && mRecords.size() > 0) {
View previousView = this;
for (TileRecord record : mRecords) {
@@ -306,31 +280,28 @@
}
}
- /**
- * Hide child views that would otherwise be clipped.
- * @return {@code true} if any child visibilities have changed.
- */
- private boolean hideOverflowingChildren(int widthMeasureSpec) {
- if (getChildCount() == 0) {
- return false;
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Measure each QS tile.
+ for (TileRecord record : mRecords) {
+ if (record.tileView.getVisibility() == GONE) continue;
+ record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
}
- boolean childVisibilityChanged = false;
- int widthRemaining = MeasureSpec.getSize(widthMeasureSpec)
- - getChildAt(0).getMeasuredWidth() - getPaddingStart() - getPaddingEnd();
- for (int i = 2; i < getChildCount(); i += 2) {
- View tileChild = getChildAt(i);
- LayoutParams lp = (LayoutParams) tileChild.getLayoutParams();
- // All Space views have 0 width; only tiles contribute to the total width.
- widthRemaining = widthRemaining
- - tileChild.getMeasuredWidth() - lp.getMarginEnd() - lp.getMarginStart();
- int newVisibility = widthRemaining < 0 ? View.GONE : View.VISIBLE;
- if (tileChild.getVisibility() != newVisibility) {
- tileChild.setVisibility(newVisibility);
- getChildAt(i - 1).setVisibility(newVisibility); // Hide spacer as well.
- childVisibilityChanged = true;
- }
- }
- return childVisibilityChanged;
+
+ int height = mCellHeight;
+ if (height < 0) height = 0;
+
+ setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
+ }
+
+ @Override
+ public int getNumVisibleTiles() {
+ return mColumns;
+ }
+
+ @Override
+ protected int getColumnStart(int column) {
+ return getPaddingStart() + column * (mCellWidth + mCellMarginHorizontal);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 45d63e0..c67165e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -56,6 +56,10 @@
public void addTile(TileRecord tile) {
mRecords.add(tile);
tile.tile.setListening(this, mListening);
+ addTileView(tile);
+ }
+
+ protected void addTileView(TileRecord tile) {
addView(tile.tileView);
}
@@ -120,19 +124,18 @@
return false;
}
- private static int exactly(int size) {
+ protected static int exactly(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- final int w = getWidth();
+
+ protected void layoutTileRecords(int numRecords) {
final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
int row = 0;
int column = 0;
// Layout each QS tile.
- for (int i = 0; i < mRecords.size(); i++, column++) {
+ for (int i = 0; i < numRecords; i++, column++) {
// If we reached the last column available to layout a tile, wrap back to the next row.
if (column == mColumns) {
column = 0;
@@ -147,12 +150,22 @@
}
}
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ layoutTileRecords(mRecords.size());
+ }
+
private int getRowTop(int row) {
return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop;
}
- private int getColumnStart(int column) {
+ protected int getColumnStart(int column) {
return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 +
column * (mCellWidth + mCellMarginHorizontal);
}
+
+ @Override
+ public int getNumVisibleTiles() {
+ return mRecords.size();
+ }
}