PagedTileLayout.java revision e4e69305e44c3d35a643c9b47bc004f1fc503746
1package com.android.systemui.qs; 2 3import android.content.Context; 4import android.util.AttributeSet; 5import android.util.Log; 6import android.view.LayoutInflater; 7import android.view.View; 8import android.view.ViewGroup; 9import com.android.internal.widget.PagerAdapter; 10import com.android.internal.widget.ViewPager; 11import com.android.systemui.R; 12import com.android.systemui.qs.QSPanel.QSTileLayout; 13import com.android.systemui.qs.QSPanel.TileRecord; 14 15import java.util.ArrayList; 16 17public class PagedTileLayout extends ViewPager implements QSTileLayout { 18 19 private static final boolean DEBUG = false; 20 21 private static final String TAG = "PagedTileLayout"; 22 23 private final ArrayList<TileRecord> mTiles = new ArrayList<TileRecord>(); 24 private final ArrayList<TilePage> mPages = new ArrayList<TilePage>(); 25 26 private PageIndicator mPageIndicator; 27 28 private int mNumPages; 29 30 public PagedTileLayout(Context context, AttributeSet attrs) { 31 super(context, attrs); 32 setAdapter(mAdapter); 33 setOnPageChangeListener(new OnPageChangeListener() { 34 @Override 35 public void onPageSelected(int position) { 36 if (mPageIndicator == null) return; 37 mPageIndicator.setLocation(position); 38 } 39 40 @Override 41 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 42 if (mPageIndicator == null) return; 43 mPageIndicator.setLocation(position + positionOffset); 44 } 45 46 @Override 47 public void onPageScrollStateChanged(int state) { 48 } 49 }); 50 setCurrentItem(0); 51 } 52 53 @Override 54 protected void onFinishInflate() { 55 super.onFinishInflate(); 56 mPageIndicator = (PageIndicator) findViewById(R.id.page_indicator); 57 ((LayoutParams) mPageIndicator.getLayoutParams()).isDecor = true; 58 59 mPages.add((TilePage) LayoutInflater.from(mContext) 60 .inflate(R.layout.qs_paged_page, this, false)); 61 } 62 63 @Override 64 public int getOffsetTop(TileRecord tile) { 65 return ((ViewGroup) tile.tileView.getParent()).getTop(); 66 } 67 68 @Override 69 public void addTile(TileRecord tile) { 70 mTiles.add(tile); 71 distributeTiles(); 72 } 73 74 @Override 75 public void removeTile(TileRecord tile) { 76 if (mTiles.remove(tile)) { 77 distributeTiles(); 78 } 79 } 80 81 private void distributeTiles() { 82 if (DEBUG) Log.d(TAG, "Distributing tiles"); 83 final int NP = mPages.size(); 84 for (int i = 0; i < NP; i++) { 85 mPages.get(i).clear(); 86 } 87 int index = 0; 88 final int NT = mTiles.size(); 89 for (int i = 0; i < NT; i++) { 90 TileRecord tile = mTiles.get(i); 91 if (mPages.get(index).isFull()) { 92 if (++index == mPages.size()) { 93 if (DEBUG) Log.d(TAG, "Adding page for " + tile.tile.getClass().getSimpleName()); 94 mPages.add((TilePage) LayoutInflater.from(mContext) 95 .inflate(R.layout.qs_paged_page, this, false)); 96 } 97 } 98 if (DEBUG) Log.d(TAG, "Adding " + tile.tile.getClass().getSimpleName() + " to " 99 + index); 100 mPages.get(index).addTile(tile); 101 } 102 if (mNumPages != index + 1) { 103 mNumPages = index + 1; 104 mPageIndicator.setNumPages(mNumPages); 105 mAdapter.notifyDataSetChanged(); 106 } 107 } 108 109 @Override 110 public void updateResources() { 111 for (int i = 0; i < mPages.size(); i++) { 112 mPages.get(i).updateResources(); 113 } 114 } 115 116 @Override 117 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 118 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 119 // The ViewPager likes to eat all of the space, instead force it to wrap to the max height 120 // of the pages. 121 int maxHeight = 0; 122 final int N = getChildCount(); 123 for (int i = 0; i < N; i++) { 124 int height = getChildAt(i).getMeasuredHeight(); 125 if (height > maxHeight) { 126 maxHeight = height; 127 } 128 } 129 setMeasuredDimension(getMeasuredWidth(), maxHeight + mPageIndicator.getMeasuredHeight()); 130 } 131 132 public static class TilePage extends TileLayout { 133 private int mMaxRows = 3; 134 135 public TilePage(Context context, AttributeSet attrs) { 136 super(context, attrs); 137 updateResources(); 138 } 139 140 public void setMaxRows(int maxRows) { 141 mMaxRows = maxRows; 142 } 143 144 @Override 145 protected int getCellHeight() { 146 return mContext.getResources().getDimensionPixelSize(R.dimen.qs_new_tile_height); 147 } 148 149 private void clear() { 150 if (DEBUG) Log.d(TAG, "Clearing page"); 151 removeAllViews(); 152 mRecords.clear(); 153 } 154 155 public boolean isFull() { 156 return mRecords.size() >= mColumns * mMaxRows; 157 } 158 } 159 160 private final PagerAdapter mAdapter = new PagerAdapter() { 161 public void destroyItem(ViewGroup container, int position, Object object) { 162 if (DEBUG) Log.d(TAG, "Destantiating " + position); 163 // TODO: Find way to clean up the extra pages. 164 container.removeView((View) object); 165 } 166 167 public Object instantiateItem(ViewGroup container, int position) { 168 if (DEBUG) Log.d(TAG, "Instantiating " + position); 169 ViewGroup view = mPages.get(position); 170 container.addView(view); 171 return view; 172 } 173 174 @Override 175 public int getCount() { 176 return mNumPages; 177 } 178 179 @Override 180 public boolean isViewFromObject(View view, Object object) { 181 return view == object; 182 } 183 }; 184} 185