Loading packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -261,6 +261,12 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { return mPages.get(0).mColumns; 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) { public void startTileReveal(Set<String> tileSpecs, final Runnable postAnimation) { if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0 || !beginFakeDrag()) { if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0 || !beginFakeDrag()) { // Do not start the reveal animation unless there are tiles to animate, multiple // Do not start the reveal animation unless there are tiles to animate, multiple Loading packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +22 −11 Original line number Original line Diff line number Diff line Loading @@ -169,6 +169,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha QSTileLayout tileLayout = mQsPanel.getTileLayout(); QSTileLayout tileLayout = mQsPanel.getTileLayout(); mAllViews.add((View) tileLayout); mAllViews.add((View) tileLayout); int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; int width = mQs.getView() != null ? mQs.getView().getMeasuredWidth() : 0; int heightDiff = height - mQs.getHeader().getBottom() int heightDiff = height - mQs.getHeader().getBottom() + mQs.getHeader().getPaddingBottom(); + mQs.getHeader().getPaddingBottom(); firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0); firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0); Loading @@ -181,7 +182,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha } } final View tileIcon = tileView.getIcon().getIconView(); final View tileIcon = tileView.getIcon().getIconView(); View view = mQs.getView(); 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. // Quick tiles. QSTileView quickTileView = mQuickQsPanel.getTileView(tile); QSTileView quickTileView = mQuickQsPanel.getTileView(tile); if (quickTileView == null) continue; if (quickTileView == null) continue; Loading @@ -192,6 +195,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha final int xDiff = loc2[0] - loc1[0]; final int xDiff = loc2[0] - loc1[0]; final int yDiff = loc2[1] - loc1[1]; final int yDiff = loc2[1] - loc1[1]; lastXDiff = loc1[0] - lastX; lastXDiff = loc1[0] - lastX; if (count < tileLayout.getNumVisibleTiles()) { // Move the quick tile right from its location to the new one. // Move the quick tile right from its location to the new one. translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff); translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff); translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); Loading @@ -205,6 +210,12 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0); translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0); translationYBuilder.addFloat(tileView, "translationY", -yDiff, 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()); mQuickQsViews.add(tileView.getIconWithBackground()); mAllViews.add(tileView.getIcon()); mAllViews.add(tileView.getIcon()); mAllViews.add(quickTileView); mAllViews.add(quickTileView); Loading packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -665,5 +665,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne void setListening(boolean listening); void setListening(boolean listening); default void setExpansion(float expansion) {} default void setExpansion(float expansion) {} int getNumVisibleTiles(); } } } } packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +71 −100 Original line number Original line Diff line number Diff line Loading @@ -18,18 +18,17 @@ package com.android.systemui.qs; import android.content.Context; import android.content.Context; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.util.AttributeSet; import android.util.AttributeSet; import android.view.Gravity; import android.view.Gravity; import android.view.View; import android.view.View; import android.widget.LinearLayout; import android.widget.LinearLayout; import android.widget.Space; import com.android.systemui.Dependency; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.State; 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.qs.customize.QSCustomizer; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.tuner.TunerService.Tunable; Loading @@ -43,6 +42,7 @@ import java.util.Collection; public class QuickQSPanel extends QSPanel { public class QuickQSPanel extends QSPanel { public static final String NUM_QUICK_TILES = "sysui_qqs_count"; public static final String NUM_QUICK_TILES = "sysui_qqs_count"; private static final String TAG = "QuickQSPanel"; private boolean mDisabledByPolicy; private boolean mDisabledByPolicy; private static int mDefaultMaxTiles; private static int mDefaultMaxTiles; Loading Loading @@ -178,121 +178,95 @@ public class QuickQSPanel extends QSPanel { super.setVisibility(visibility); 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; private boolean mListening; /** Size of the QS tile (width & height). */ private int mTileDimensionSize; public HeaderTileLayout(Context context) { public HeaderTileLayout(Context context) { super(context); super(context); setClipChildren(false); setClipChildren(false); setClipToPadding(false); setClipToPadding(false); mTileDimensionSize = mContext.getResources().getDimensionPixelSize( R.dimen.qs_quick_tile_size); updateLayoutParams(); } } @Override @Override protected void onConfigurationChanged(Configuration newConfig) { protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig); updateLayoutParams(); updateResources(); } @Override public void onFinishInflate(){ updateResources(); } } private void updateLayoutParams() { private void updateLayoutParams() { setGravity(Gravity.CENTER); int width = getResources().getDimensionPixelSize(R.dimen.qs_quick_layout_width); 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; lp.gravity = Gravity.CENTER_HORIZONTAL; setLayoutParams(lp); setLayoutParams(lp); } } /** private LayoutParams generateTileLayoutParams() { * Returns {@link LayoutParams} based on the given {@code spaceWidth}. If the width is 0, LayoutParams lp = new LayoutParams(mCellWidth, mCellHeight); * 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; return lp; } } @Override @Override public void setListening(boolean listening) { protected void addTileView(TileRecord tile) { 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()); 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; return lp; } } @Override @Override public void removeTile(TileRecord tile) { protected void onLayout(boolean changed, int l, int t, int r, int b) { int childIndex = getChildIndex(tile.tileView); // We only care about clipping on the right side // Remove the tile. Rect bounds = new Rect(0, 0, r - l, 10000); removeViewAt(childIndex); setClipBounds(bounds); if (getChildCount() != 0) { // Remove its spacer as well. removeViewAt(childIndex); } mRecords.remove(tile); tile.tile.setListening(this, false); } private int getChildIndex(QSTileView tileView) { calculateColumns(); final int childViewCount = getChildCount(); for (int i = 0; i < childViewCount; i++) { for (int i = 0; i < mRecords.size(); i++) { if (getChildAt(i) == tileView) { mRecords.get(i).tileView.setVisibility( i < mColumns ? View.VISIBLE : View.GONE); return i; } } return -1; } } @Override setAccessibilityOrder(); public int getOffsetTop(TileRecord tile) { layoutTileRecords(mColumns); return 0; } } @Override @Override public boolean updateResources() { public boolean updateResources() { // No resources here. mCellWidth = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size); mCellHeight = mCellWidth; updateLayoutParams(); return false; return false; } } @Override private boolean calculateColumns() { public boolean hasOverlappingRendering() { int prevNumColumns = mColumns; return false; int maxTiles = mRecords.size(); if (maxTiles == 0){ // Early return during setup mColumns = 0; return true; } } @Override final int availableWidth = getMeasuredWidth() - getPaddingStart() - getPaddingEnd(); protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int leftoverWithespace = availableWidth - maxTiles * mCellWidth; super.onMeasure(widthMeasureSpec, heightMeasureSpec); final int smallestHorizontalMarginNeeded = leftoverWithespace / (maxTiles - 1); if (hideOverflowingChildren(widthMeasureSpec)) { return; // Rely on visibility change to trigger remeasure. 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) { if (mRecords != null && mRecords.size() > 0) { View previousView = this; View previousView = this; for (TileRecord record : mRecords) { for (TileRecord record : mRecords) { Loading @@ -306,31 +280,28 @@ public class QuickQSPanel extends QSPanel { } } } } /** @Override * Hide child views that would otherwise be clipped. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { * @return {@code true} if any child visibilities have changed. // Measure each QS tile. */ for (TileRecord record : mRecords) { private boolean hideOverflowingChildren(int widthMeasureSpec) { if (record.tileView.getVisibility() == GONE) continue; if (getChildCount() == 0) { record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight)); return false; } } boolean childVisibilityChanged = false; int widthRemaining = MeasureSpec.getSize(widthMeasureSpec) int height = mCellHeight; - getChildAt(0).getMeasuredWidth() - getPaddingStart() - getPaddingEnd(); if (height < 0) height = 0; for (int i = 2; i < getChildCount(); i += 2) { View tileChild = getChildAt(i); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height); LayoutParams lp = (LayoutParams) tileChild.getLayoutParams(); } // All Space views have 0 width; only tiles contribute to the total width. widthRemaining = widthRemaining @Override - tileChild.getMeasuredWidth() - lp.getMarginEnd() - lp.getMarginStart(); public int getNumVisibleTiles() { int newVisibility = widthRemaining < 0 ? View.GONE : View.VISIBLE; return mColumns; if (tileChild.getVisibility() != newVisibility) { } tileChild.setVisibility(newVisibility); getChildAt(i - 1).setVisibility(newVisibility); // Hide spacer as well. @Override childVisibilityChanged = true; protected int getColumnStart(int column) { } return getPaddingStart() + column * (mCellWidth + mCellMarginHorizontal); } return childVisibilityChanged; } } } } } } packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +19 −6 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,10 @@ public class TileLayout extends ViewGroup implements QSTileLayout { public void addTile(TileRecord tile) { public void addTile(TileRecord tile) { mRecords.add(tile); mRecords.add(tile); tile.tile.setListening(this, mListening); tile.tile.setListening(this, mListening); addTileView(tile); } protected void addTileView(TileRecord tile) { addView(tile.tileView); addView(tile.tileView); } } Loading Loading @@ -120,19 +124,18 @@ public class TileLayout extends ViewGroup implements QSTileLayout { return false; return false; } } private static int exactly(int size) { protected static int exactly(int size) { return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void layoutTileRecords(int numRecords) { final int w = getWidth(); final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; int row = 0; int row = 0; int column = 0; int column = 0; // Layout each QS tile. // 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 we reached the last column available to layout a tile, wrap back to the next row. if (column == mColumns) { if (column == mColumns) { column = 0; column = 0; Loading @@ -147,12 +150,22 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } } } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { layoutTileRecords(mRecords.size()); } private int getRowTop(int row) { private int getRowTop(int row) { return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop; return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop; } } private int getColumnStart(int column) { protected int getColumnStart(int column) { return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 + return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 + column * (mCellWidth + mCellMarginHorizontal); column * (mCellWidth + mCellMarginHorizontal); } } @Override public int getNumVisibleTiles() { return mRecords.size(); } } } Loading
packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -261,6 +261,12 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { return mPages.get(0).mColumns; 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) { public void startTileReveal(Set<String> tileSpecs, final Runnable postAnimation) { if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0 || !beginFakeDrag()) { if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0 || !beginFakeDrag()) { // Do not start the reveal animation unless there are tiles to animate, multiple // Do not start the reveal animation unless there are tiles to animate, multiple Loading
packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +22 −11 Original line number Original line Diff line number Diff line Loading @@ -169,6 +169,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha QSTileLayout tileLayout = mQsPanel.getTileLayout(); QSTileLayout tileLayout = mQsPanel.getTileLayout(); mAllViews.add((View) tileLayout); mAllViews.add((View) tileLayout); int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; int height = mQs.getView() != null ? mQs.getView().getMeasuredHeight() : 0; int width = mQs.getView() != null ? mQs.getView().getMeasuredWidth() : 0; int heightDiff = height - mQs.getHeader().getBottom() int heightDiff = height - mQs.getHeader().getBottom() + mQs.getHeader().getPaddingBottom(); + mQs.getHeader().getPaddingBottom(); firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0); firstPageBuilder.addFloat(tileLayout, "translationY", heightDiff, 0); Loading @@ -181,7 +182,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha } } final View tileIcon = tileView.getIcon().getIconView(); final View tileIcon = tileView.getIcon().getIconView(); View view = mQs.getView(); 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. // Quick tiles. QSTileView quickTileView = mQuickQsPanel.getTileView(tile); QSTileView quickTileView = mQuickQsPanel.getTileView(tile); if (quickTileView == null) continue; if (quickTileView == null) continue; Loading @@ -192,6 +195,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha final int xDiff = loc2[0] - loc1[0]; final int xDiff = loc2[0] - loc1[0]; final int yDiff = loc2[1] - loc1[1]; final int yDiff = loc2[1] - loc1[1]; lastXDiff = loc1[0] - lastX; lastXDiff = loc1[0] - lastX; if (count < tileLayout.getNumVisibleTiles()) { // Move the quick tile right from its location to the new one. // Move the quick tile right from its location to the new one. translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff); translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff); translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff); Loading @@ -205,6 +210,12 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0); translationXBuilder.addFloat(tileView, "translationX", -xDiff, 0); translationYBuilder.addFloat(tileView, "translationY", -yDiff, 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()); mQuickQsViews.add(tileView.getIconWithBackground()); mAllViews.add(tileView.getIcon()); mAllViews.add(tileView.getIcon()); mAllViews.add(quickTileView); mAllViews.add(quickTileView); Loading
packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -665,5 +665,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne void setListening(boolean listening); void setListening(boolean listening); default void setExpansion(float expansion) {} default void setExpansion(float expansion) {} int getNumVisibleTiles(); } } } }
packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +71 −100 Original line number Original line Diff line number Diff line Loading @@ -18,18 +18,17 @@ package com.android.systemui.qs; import android.content.Context; import android.content.Context; import android.content.res.Configuration; import android.content.res.Configuration; import android.graphics.Rect; import android.util.AttributeSet; import android.util.AttributeSet; import android.view.Gravity; import android.view.Gravity; import android.view.View; import android.view.View; import android.widget.LinearLayout; import android.widget.LinearLayout; import android.widget.Space; import com.android.systemui.Dependency; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.plugins.qs.QSTile.State; 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.qs.customize.QSCustomizer; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.tuner.TunerService.Tunable; Loading @@ -43,6 +42,7 @@ import java.util.Collection; public class QuickQSPanel extends QSPanel { public class QuickQSPanel extends QSPanel { public static final String NUM_QUICK_TILES = "sysui_qqs_count"; public static final String NUM_QUICK_TILES = "sysui_qqs_count"; private static final String TAG = "QuickQSPanel"; private boolean mDisabledByPolicy; private boolean mDisabledByPolicy; private static int mDefaultMaxTiles; private static int mDefaultMaxTiles; Loading Loading @@ -178,121 +178,95 @@ public class QuickQSPanel extends QSPanel { super.setVisibility(visibility); 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; private boolean mListening; /** Size of the QS tile (width & height). */ private int mTileDimensionSize; public HeaderTileLayout(Context context) { public HeaderTileLayout(Context context) { super(context); super(context); setClipChildren(false); setClipChildren(false); setClipToPadding(false); setClipToPadding(false); mTileDimensionSize = mContext.getResources().getDimensionPixelSize( R.dimen.qs_quick_tile_size); updateLayoutParams(); } } @Override @Override protected void onConfigurationChanged(Configuration newConfig) { protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig); updateLayoutParams(); updateResources(); } @Override public void onFinishInflate(){ updateResources(); } } private void updateLayoutParams() { private void updateLayoutParams() { setGravity(Gravity.CENTER); int width = getResources().getDimensionPixelSize(R.dimen.qs_quick_layout_width); 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; lp.gravity = Gravity.CENTER_HORIZONTAL; setLayoutParams(lp); setLayoutParams(lp); } } /** private LayoutParams generateTileLayoutParams() { * Returns {@link LayoutParams} based on the given {@code spaceWidth}. If the width is 0, LayoutParams lp = new LayoutParams(mCellWidth, mCellHeight); * 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; return lp; } } @Override @Override public void setListening(boolean listening) { protected void addTileView(TileRecord tile) { 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()); 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; return lp; } } @Override @Override public void removeTile(TileRecord tile) { protected void onLayout(boolean changed, int l, int t, int r, int b) { int childIndex = getChildIndex(tile.tileView); // We only care about clipping on the right side // Remove the tile. Rect bounds = new Rect(0, 0, r - l, 10000); removeViewAt(childIndex); setClipBounds(bounds); if (getChildCount() != 0) { // Remove its spacer as well. removeViewAt(childIndex); } mRecords.remove(tile); tile.tile.setListening(this, false); } private int getChildIndex(QSTileView tileView) { calculateColumns(); final int childViewCount = getChildCount(); for (int i = 0; i < childViewCount; i++) { for (int i = 0; i < mRecords.size(); i++) { if (getChildAt(i) == tileView) { mRecords.get(i).tileView.setVisibility( i < mColumns ? View.VISIBLE : View.GONE); return i; } } return -1; } } @Override setAccessibilityOrder(); public int getOffsetTop(TileRecord tile) { layoutTileRecords(mColumns); return 0; } } @Override @Override public boolean updateResources() { public boolean updateResources() { // No resources here. mCellWidth = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size); mCellHeight = mCellWidth; updateLayoutParams(); return false; return false; } } @Override private boolean calculateColumns() { public boolean hasOverlappingRendering() { int prevNumColumns = mColumns; return false; int maxTiles = mRecords.size(); if (maxTiles == 0){ // Early return during setup mColumns = 0; return true; } } @Override final int availableWidth = getMeasuredWidth() - getPaddingStart() - getPaddingEnd(); protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int leftoverWithespace = availableWidth - maxTiles * mCellWidth; super.onMeasure(widthMeasureSpec, heightMeasureSpec); final int smallestHorizontalMarginNeeded = leftoverWithespace / (maxTiles - 1); if (hideOverflowingChildren(widthMeasureSpec)) { return; // Rely on visibility change to trigger remeasure. 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) { if (mRecords != null && mRecords.size() > 0) { View previousView = this; View previousView = this; for (TileRecord record : mRecords) { for (TileRecord record : mRecords) { Loading @@ -306,31 +280,28 @@ public class QuickQSPanel extends QSPanel { } } } } /** @Override * Hide child views that would otherwise be clipped. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { * @return {@code true} if any child visibilities have changed. // Measure each QS tile. */ for (TileRecord record : mRecords) { private boolean hideOverflowingChildren(int widthMeasureSpec) { if (record.tileView.getVisibility() == GONE) continue; if (getChildCount() == 0) { record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight)); return false; } } boolean childVisibilityChanged = false; int widthRemaining = MeasureSpec.getSize(widthMeasureSpec) int height = mCellHeight; - getChildAt(0).getMeasuredWidth() - getPaddingStart() - getPaddingEnd(); if (height < 0) height = 0; for (int i = 2; i < getChildCount(); i += 2) { View tileChild = getChildAt(i); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height); LayoutParams lp = (LayoutParams) tileChild.getLayoutParams(); } // All Space views have 0 width; only tiles contribute to the total width. widthRemaining = widthRemaining @Override - tileChild.getMeasuredWidth() - lp.getMarginEnd() - lp.getMarginStart(); public int getNumVisibleTiles() { int newVisibility = widthRemaining < 0 ? View.GONE : View.VISIBLE; return mColumns; if (tileChild.getVisibility() != newVisibility) { } tileChild.setVisibility(newVisibility); getChildAt(i - 1).setVisibility(newVisibility); // Hide spacer as well. @Override childVisibilityChanged = true; protected int getColumnStart(int column) { } return getPaddingStart() + column * (mCellWidth + mCellMarginHorizontal); } return childVisibilityChanged; } } } } } }
packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +19 −6 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,10 @@ public class TileLayout extends ViewGroup implements QSTileLayout { public void addTile(TileRecord tile) { public void addTile(TileRecord tile) { mRecords.add(tile); mRecords.add(tile); tile.tile.setListening(this, mListening); tile.tile.setListening(this, mListening); addTileView(tile); } protected void addTileView(TileRecord tile) { addView(tile.tileView); addView(tile.tileView); } } Loading Loading @@ -120,19 +124,18 @@ public class TileLayout extends ViewGroup implements QSTileLayout { return false; return false; } } private static int exactly(int size) { protected static int exactly(int size) { return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void layoutTileRecords(int numRecords) { final int w = getWidth(); final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; int row = 0; int row = 0; int column = 0; int column = 0; // Layout each QS tile. // 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 we reached the last column available to layout a tile, wrap back to the next row. if (column == mColumns) { if (column == mColumns) { column = 0; column = 0; Loading @@ -147,12 +150,22 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } } } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { layoutTileRecords(mRecords.size()); } private int getRowTop(int row) { private int getRowTop(int row) { return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop; return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop; } } private int getColumnStart(int column) { protected int getColumnStart(int column) { return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 + return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 + column * (mCellWidth + mCellMarginHorizontal); column * (mCellWidth + mCellMarginHorizontal); } } @Override public int getNumVisibleTiles() { return mRecords.size(); } } }