1b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn/* 2b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Copyright (C) 2014 The Android Open Source Project 3b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 4b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * in compliance with the License. You may obtain a copy of the License at 6b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 7b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * http://www.apache.org/licenses/LICENSE-2.0 8b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 9b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Unless required by applicable law or agreed to in writing, software distributed under the License 10b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * or implied. See the License for the specific language governing permissions and limitations under 12b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * the License. 13b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 14b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbournpackage android.support.v17.leanback.widget; 15b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 16b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbournimport android.support.v4.util.CircularArray; 17b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 18b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbournimport java.io.PrintWriter; 19adc2a01f5701cbcc044754119b572abcf31c7c5fDake Guimport java.util.ArrayList; 20adc2a01f5701cbcc044754119b572abcf31c7c5fDake Guimport java.util.List; 21b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 22b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn/** 23b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * A dynamic data structure that maintains staggered grid position information 24b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * for each individual child. The algorithm ensures that each row will be kept 25b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * as balanced as possible when prepending and appending a child. 26b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 27b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <p> 28b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * You may keep view {@link StaggeredGrid.Location} inside StaggeredGrid as much 29b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * as possible since prepending and appending views is not symmetric: layout 30b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * going from 0 to N will likely produce a different result than layout going 31b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * from N to 0 for the staggered cases. If a user scrolls from 0 to N then 32b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * scrolls back to 0 and we don't keep history location information, edges of 33b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * the very beginning of rows will not be aligned. It is recommended to keep a 34b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * list of tens of thousands of {@link StaggeredGrid.Location}s which will be 35b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * big enough to remember a typical user's scroll history. There are situations 36b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * where StaggeredGrid falls back to the simple case where we do not need save a 37b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * huge list of locations inside StaggeredGrid: 38b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <ul> 39b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <li>Only one row (e.g., a single row listview)</li> 40b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <li> Each item has the same length (not staggered at all)</li> 41b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * </ul> 42b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 43b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <p> 44b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * This class is abstract and can be replaced with different implementations. 45b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 46b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbournabstract class StaggeredGrid { 47b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 48b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 49b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * TODO: document this 50b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 51b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public static interface Provider { 52b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 53b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Return how many items are in the adapter. 54b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 55b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public abstract int getCount(); 56b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 57b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 58b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Create the object at a given row. 59b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 60b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public abstract void createItem(int index, int row, boolean append); 61b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 62b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 63b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 64b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Location of an item in the grid. For now it only saves row index but 65b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * more information may be added in the future. 66b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 67b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final static class Location { 68b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 69b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * The index of the row for this Location. 70b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 71b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final int row; 72b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 73b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 74b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Create a Location with the given row index. 75b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 76b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public Location(int row) { 77b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn this.row = row; 78b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 79b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 80b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 81b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 82b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * TODO: document this 83b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 84b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final static class Row { 85b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 86b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * first view start location 87b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 88b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public int low; 89b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 90b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * last view end location 91b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 92b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public int high; 93b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 94b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 95b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected Provider mProvider; 96b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected int mNumRows = 1; // mRows.length 97b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected Row[] mRows; 98b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected CircularArray<Location> mLocations = new CircularArray<Location>(64); 99adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu private ArrayList<Integer>[] mTmpItemPositionsInRows; 100e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing protected boolean mReversedFlow; 101b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 102b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 103b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * A constant representing a default starting index, indicating that the 104b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * developer did not provide a start index. 105b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 106b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public static final int START_DEFAULT = -1; 107b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 108b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn // the first index that grid will layout 109b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected int mStartIndex = START_DEFAULT; 110b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn // the row to layout the first index 111b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected int mStartRow = START_DEFAULT; 112b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 113b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected int mFirstIndex = -1; 114b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 115e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing public void setReversedFlow(boolean reversedFlow) { 116e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing mReversedFlow = reversedFlow; 117e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 118e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing 119b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 120b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Sets the {@link Provider} for this staggered grid. 121b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 122b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * @param provider The provider for this staggered grid. 123b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 124b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public void setProvider(Provider provider) { 125b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mProvider = provider; 126b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 127b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 128b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 129b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Sets the array of {@link Row}s to fill into. For views that represent a 130b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * horizontal list, this will be the rows of the view. For views that 131b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * represent a vertical list, this will be the columns. 132b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 133b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * @param row The array of {@link Row}s to be filled. 134b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 135b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final void setRows(Row[] row) { 136b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (row == null || row.length == 0) { 137b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn throw new IllegalArgumentException(); 138b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 139b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mNumRows = row.length; 140b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mRows = row; 141adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu mTmpItemPositionsInRows = new ArrayList[mNumRows]; 142adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu for (int i = 0; i < mNumRows; i++) { 143adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu mTmpItemPositionsInRows[i] = new ArrayList(32); 144adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu } 145b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 146b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 147b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 148b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Returns the number of rows in the staggered grid. 149b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 150b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final int getNumRows() { 151b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return mNumRows; 152b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 153b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 154b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 155b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Set the first item index and the row index to load when there are no 156b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * items. 157b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 158b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * @param startIndex the index of the first item 159b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * @param startRow the index of the row 160b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 161b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final void setStart(int startIndex, int startRow) { 162b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mStartIndex = startIndex; 163b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mStartRow = startRow; 164b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 165b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 166b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 167b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Returns the first index in the staggered grid. 168b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 169b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final int getFirstIndex() { 170b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return mFirstIndex; 171b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 172b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 173b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 174b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Returns the last index in the staggered grid. 175b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 176b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final int getLastIndex() { 177b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return mFirstIndex + mLocations.size() - 1; 178b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 179b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 180b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 181b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Returns the size of the saved {@link Location}s. 182b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 183b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final int getSize() { 184b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return mLocations.size(); 185b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 186b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 187b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 188b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Returns the {@link Location} at the given index. 189b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 190b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final Location getLocation(int index) { 191b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mLocations.size() == 0) { 192b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return null; 193b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 194b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return mLocations.get(index - mFirstIndex); 195b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 196b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 197b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 198b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Removes the first element. 199b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 200b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final void removeFirst() { 201b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mFirstIndex++; 202b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mLocations.popFirst(); 203b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 204b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 205b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 206b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Removes the last element. 207b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 208b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final void removeLast() { 209b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mLocations.popLast(); 210b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 211b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 212b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public final void debugPrint(PrintWriter pw) { 213b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn for (int i = 0, size = mLocations.size(); i < size; i++) { 214b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn Location loc = mLocations.get(i); 215b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn pw.print("<" + (mFirstIndex + i) + "," + loc.row + ">"); 216b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn pw.print(" "); 217b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn pw.println(); 218b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 219b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 220b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 221b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final int getMaxHighRowIndex() { 222b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn int maxHighRowIndex = 0; 223b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn for (int i = 1; i < mNumRows; i++) { 224b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mRows[i].high > mRows[maxHighRowIndex].high) { 225b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn maxHighRowIndex = i; 226b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 227b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 228b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return maxHighRowIndex; 229b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 230b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 231b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final int getMinHighRowIndex() { 232b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn int minHighRowIndex = 0; 233b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn for (int i = 1; i < mNumRows; i++) { 234b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mRows[i].high < mRows[minHighRowIndex].high) { 235b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn minHighRowIndex = i; 236b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 237b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 238b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return minHighRowIndex; 239b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 240b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 241b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final Location appendItemToRow(int itemIndex, int rowIndex) { 242b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn Location loc = new Location(rowIndex); 243b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mLocations.size() == 0) { 244b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mFirstIndex = itemIndex; 245b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 246b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mLocations.addLast(loc); 24779b86b227e6794937ec311522b50e727f8eec263Dake Gu mProvider.createItem(itemIndex, rowIndex, true); 248b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return loc; 249b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 250b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 251b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 252b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Append items until the high edge reaches upTo. 253b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 254e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing public abstract void appendItems(int toLimit); 255b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 256b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final int getMaxLowRowIndex() { 257b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn int maxLowRowIndex = 0; 258b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn for (int i = 1; i < mNumRows; i++) { 259b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mRows[i].low > mRows[maxLowRowIndex].low) { 260b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn maxLowRowIndex = i; 261b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 262b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 263b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return maxLowRowIndex; 264b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 265b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 266b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final int getMinLowRowIndex() { 267b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn int minLowRowIndex = 0; 268b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn for (int i = 1; i < mNumRows; i++) { 269b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn if (mRows[i].low < mRows[minLowRowIndex].low) { 270b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn minLowRowIndex = i; 271b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 272b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 273b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return minLowRowIndex; 274b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 275b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 276b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn protected final Location prependItemToRow(int itemIndex, int rowIndex) { 277b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn Location loc = new Location(rowIndex); 278b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mFirstIndex = itemIndex; 279b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn mLocations.addFirst(loc); 28079b86b227e6794937ec311522b50e727f8eec263Dake Gu mProvider.createItem(itemIndex, rowIndex, false); 281b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn return loc; 282b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn } 283b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 284b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 285adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu * Return array of Lists for all rows, each List contains item positions 286adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu * on that row between startPos(included) and endPositions(included). 287adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu * Returned value is read only, do not change it. 288adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu */ 289adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu public final List<Integer>[] getItemPositionsInRows(int startPos, int endPos) { 290adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu for (int i = 0; i < mNumRows; i++) { 291adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu mTmpItemPositionsInRows[i].clear(); 292adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu } 293adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu if (startPos >= 0) { 294adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu for (int i = startPos; i <= endPos; i++) { 295adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu mTmpItemPositionsInRows[getLocation(i).row].add(i); 296adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu } 297adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu } 298adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu return mTmpItemPositionsInRows; 299adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu } 300adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu 301adc2a01f5701cbcc044754119b572abcf31c7c5fDake Gu /** 302b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Prepend items until the low edge reaches downTo. 303b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 304e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing public abstract void prependItems(int toLimit); 305b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn 306b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn /** 307b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * Strip items, keep a contiguous subset of items; the subset should include 308b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * at least one item on every row that currently has at least one item. 309b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * 310b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * <p> 311b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn * TODO: document this better 312b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn */ 313b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn public abstract void stripDownTo(int itemIndex); 314b9537aff4a6ff5231030799cdaf931c27fb9579bTim Kilbourn} 315