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