blob: c612600ac82e5e1b95f69629ef71ab3a2a4b5fe8 [file] [log] [blame]
Jason Monkcaf37622015-08-18 12:33:50 -04001package 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);
Jason Monkbd6dbb02015-09-03 15:46:25 -040078// // TODO: Do something smarter here.
79// distributeTiles();
Jason Monkcaf37622015-08-18 12:33:50 -040080 }
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 }
185
Jason Monkbd6dbb02015-09-03 15:46:25 -0400186 public void setMaxRows(int maxRows) {
187 mMaxRows = maxRows;
188 }
189
Jason Monkcaf37622015-08-18 12:33:50 -0400190 private void clear() {
191 if (DEBUG) Log.d(TAG, "Clearing page");
192 removeAllViews();
193 mRecords.clear();
194 }
195
Jason Monkbd6dbb02015-09-03 15:46:25 -0400196 public boolean isFull() {
Jason Monkcaf37622015-08-18 12:33:50 -0400197 return mRecords.size() >= mColumns * mMaxRows;
198 }
199 }
200
201 private final PagerAdapter mAdapter = new PagerAdapter() {
202 public void destroyItem(ViewGroup container, int position, Object object) {
203 if (DEBUG) Log.d(TAG, "Destantiating " + position);
204 // TODO: Find way to clean up the extra pages.
205 container.removeView((View) object);
206 }
207
208 public Object instantiateItem(ViewGroup container, int position) {
209 if (DEBUG) Log.d(TAG, "Instantiating " + position);
210 ViewGroup view = position == 0 ? mFirstPage : mPages.get(position);
211 container.addView(view);
212 return view;
213 }
214
215 @Override
216 public int getCount() {
217 return mNumPages;
218 }
219
220 @Override
221 public boolean isViewFromObject(View view, Object object) {
222 return view == object;
223 }
224 };
225}