PagedTileLayout.java revision b9c00197021ae0bf1172a1e332e047e30d3e4afa
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 android.widget.LinearLayout; 10 11import com.android.internal.widget.PagerAdapter; 12import com.android.internal.widget.ViewPager; 13import com.android.systemui.R; 14import com.android.systemui.qs.QSPanel.QSTileLayout; 15import com.android.systemui.qs.QSPanel.TileRecord; 16 17import java.util.ArrayList; 18 19public class PagedTileLayout extends ViewPager implements QSTileLayout { 20 21 private static final boolean DEBUG = false; 22 23 private static final String TAG = "PagedTileLayout"; 24 25 private final ArrayList<TileRecord> mTiles = new ArrayList<TileRecord>(); 26 private final ArrayList<TilePage> mPages = new ArrayList<TilePage>(); 27 28 private FirstPage mFirstPage; 29 private PageIndicator mPageIndicator; 30 31 private int mNumPages; 32 33 public PagedTileLayout(Context context, AttributeSet attrs) { 34 super(context, attrs); 35 setAdapter(mAdapter); 36 setOnPageChangeListener(new OnPageChangeListener() { 37 @Override 38 public void onPageSelected(int position) { 39 if (mPageIndicator == null) return; 40 mPageIndicator.setLocation(position); 41 } 42 43 @Override 44 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 45 if (mPageIndicator == null) return; 46 mPageIndicator.setLocation(position + positionOffset); 47 } 48 49 @Override 50 public void onPageScrollStateChanged(int state) { 51 } 52 }); 53 setCurrentItem(0); 54 } 55 56 @Override 57 protected void onFinishInflate() { 58 super.onFinishInflate(); 59 mPageIndicator = (PageIndicator) findViewById(R.id.page_indicator); 60 ((LayoutParams) mPageIndicator.getLayoutParams()).isDecor = true; 61 62 mFirstPage = (FirstPage) findViewById(R.id.first_page); 63 removeView(mFirstPage); // We don't actually want this on the view yet, just inflated. 64 mPages.add(mFirstPage.mTilePage); 65 } 66 67 @Override 68 public int getOffsetTop(TileRecord tile) { 69 if (tile.tileView.getParent() == mFirstPage.mTilePage) { 70 return mFirstPage.getTop() + mFirstPage.mTilePage.getTop(); 71 } 72 return ((ViewGroup) tile.tileView.getParent()).getTop(); 73 } 74 75 @Override 76 public void setTileVisibility(TileRecord tile, int visibility) { 77 tile.tileView.setVisibility(visibility); 78// // TODO: Do something smarter here. 79// distributeTiles(); 80 } 81 82 @Override 83 public void addTile(TileRecord tile) { 84 mTiles.add(tile); 85 distributeTiles(); 86 } 87 88 @Override 89 public void removeTile(TileRecord tile) { 90 if (mTiles.remove(tile)) { 91 distributeTiles(); 92 } 93 } 94 95 private void distributeTiles() { 96 if (DEBUG) Log.d(TAG, "Distributing tiles"); 97 mFirstPage.mQuickQuickTiles.removeAllViews(); 98 final int NP = mPages.size(); 99 for (int i = 0; i < NP; i++) { 100 mPages.get(i).clear(); 101 } 102 int index = 0; 103 final int NT = mTiles.size(); 104 for (int i = 0; i < NT; i++) { 105 TileRecord tile = mTiles.get(i); 106 if (tile.tile.getTileType() == QSTileView.QS_TYPE_QUICK) { 107 tile.tileView.setType(QSTileView.QS_TYPE_QUICK); 108 mFirstPage.mQuickQuickTiles.addView(tile.tileView); 109 continue; 110 } 111 if (mPages.get(index).isFull()) { 112 if (++index == mPages.size()) { 113 if (DEBUG) Log.d(TAG, "Adding page for " + tile.tile.getClass().getSimpleName()); 114 mPages.add((TilePage) LayoutInflater.from(mContext) 115 .inflate(R.layout.qs_paged_page, this, false)); 116 } 117 } 118 if (DEBUG) Log.d(TAG, "Adding " + tile.tile.getClass().getSimpleName() + " to " 119 + index); 120 mPages.get(index).addTile(tile); 121 } 122 if (mNumPages != index + 1) { 123 mNumPages = index + 1; 124 mPageIndicator.setNumPages(mNumPages); 125 mAdapter.notifyDataSetChanged(); 126 } 127 } 128 129 @Override 130 public void updateResources() { 131 for (int i = 0; i < mPages.size(); i++) { 132 mPages.get(i).updateResources(); 133 } 134 } 135 136 @Override 137 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 138 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 139 // The ViewPager likes to eat all of the space, instead force it to wrap to the max height 140 // of the pages. 141 int maxHeight = 0; 142 final int N = getChildCount(); 143 for (int i = 0; i < N; i++) { 144 int height = getChildAt(i).getMeasuredHeight(); 145 if (height > maxHeight) { 146 maxHeight = height; 147 } 148 } 149 setMeasuredDimension(getMeasuredWidth(), maxHeight + mPageIndicator.getMeasuredHeight()); 150 } 151 152 public static class FirstPage extends LinearLayout { 153 private LinearLayout mQuickQuickTiles; 154 private TilePage mTilePage; 155 156 public FirstPage(Context context, AttributeSet attrs) { 157 super(context, attrs); 158 } 159 160 @Override 161 protected void onFinishInflate() { 162 super.onFinishInflate(); 163 mQuickQuickTiles = (LinearLayout) findViewById(R.id.quick_tile_layout); 164 mTilePage = (TilePage) findViewById(R.id.tile_page); 165 // Less rows on first page, because it needs room for the quick tiles. 166 mTilePage.mMaxRows = 3; 167 } 168 169 @Override 170 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 171 // The ViewPager will try to make us taller, don't do it unless we need to. 172 heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), 173 MeasureSpec.AT_MOST); 174 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 175 } 176 } 177 178 public static class TilePage extends TileLayout { 179 private int mMaxRows = 4; 180 181 public TilePage(Context context, AttributeSet attrs) { 182 super(context, attrs); 183 mAllowDual = false; 184 updateResources(); 185 } 186 187 public void setMaxRows(int maxRows) { 188 mMaxRows = maxRows; 189 } 190 191 private void clear() { 192 if (DEBUG) Log.d(TAG, "Clearing page"); 193 removeAllViews(); 194 mRecords.clear(); 195 } 196 197 public boolean isFull() { 198 return mRecords.size() >= mColumns * mMaxRows; 199 } 200 } 201 202 private final PagerAdapter mAdapter = new PagerAdapter() { 203 public void destroyItem(ViewGroup container, int position, Object object) { 204 if (DEBUG) Log.d(TAG, "Destantiating " + position); 205 // TODO: Find way to clean up the extra pages. 206 container.removeView((View) object); 207 } 208 209 public Object instantiateItem(ViewGroup container, int position) { 210 if (DEBUG) Log.d(TAG, "Instantiating " + position); 211 ViewGroup view = position == 0 ? mFirstPage : mPages.get(position); 212 container.addView(view); 213 return view; 214 } 215 216 @Override 217 public int getCount() { 218 return mNumPages; 219 } 220 221 @Override 222 public boolean isViewFromObject(View view, Object object) { 223 return view == object; 224 } 225 }; 226} 227