StaggeredGridDefault.java revision 8b068ddbbf22a246eab49ec25a2f7c3abfbdca51
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16/** 17 * A default implementation of {@link StaggeredGrid}. 18 * 19 * This implementation tries to fill items in consecutive row order. The next 20 * item is always in same row or in the next row. 21 */ 22final class StaggeredGridDefault extends StaggeredGrid { 23 24 @Override 25 public void appendItems(int upTo) { 26 int count = mProvider.getCount(); 27 int itemIndex; 28 int rowIndex; 29 if (mLocations.size() > 0) { 30 itemIndex = getLastIndex() + 1; 31 rowIndex = (mLocations.getLast().row + 1) % mNumRows; 32 } else { 33 itemIndex = mStartIndex != START_DEFAULT ? mStartIndex : 0; 34 rowIndex = mStartRow != START_DEFAULT ? mStartRow : itemIndex % mNumRows; 35 } 36 37 top_loop: 38 while (true) { 39 // find highest row (.high is biggest) 40 int maxHighRowIndex = mLocations.size() > 0 ? getMaxHighRowIndex() : -1; 41 int maxHigh = maxHighRowIndex != -1 ? mRows[maxHighRowIndex].high : Integer.MIN_VALUE; 42 // fill from current row till last row so that each row will grow longer than 43 // the previous highest row. 44 for (; rowIndex < mNumRows; rowIndex++) { 45 // fill one item to a row 46 if (itemIndex == count) { 47 break top_loop; 48 } 49 appendItemToRow(itemIndex++, rowIndex); 50 // fill more item to the row to make sure this row is longer than 51 // the previous highest row. 52 if (maxHighRowIndex == -1) { 53 maxHighRowIndex = getMaxHighRowIndex(); 54 maxHigh = mRows[maxHighRowIndex].high; 55 } else if (rowIndex != maxHighRowIndex) { 56 while (mRows[rowIndex].high < maxHigh) { 57 if (itemIndex == count) { 58 break top_loop; 59 } 60 appendItemToRow(itemIndex++, rowIndex); 61 } 62 } 63 } 64 if (mRows[getMinHighRowIndex()].high >= upTo) { 65 break; 66 } 67 // start fill from row 0 again 68 rowIndex = 0; 69 } 70 } 71 72 @Override 73 public void prependItems(int downTo) { 74 if (mProvider.getCount() <= 0) return; 75 int itemIndex; 76 int rowIndex; 77 if (mLocations.size() > 0) { 78 itemIndex = getFirstIndex() - 1; 79 rowIndex = mLocations.getFirst().row; 80 if (rowIndex == 0) { 81 rowIndex = mNumRows - 1; 82 } else { 83 rowIndex--; 84 } 85 } else { 86 itemIndex = mStartIndex != START_DEFAULT ? mStartIndex : 0; 87 rowIndex = mStartRow != START_DEFAULT ? mStartRow : itemIndex % mNumRows; 88 } 89 90 top_loop: 91 while (true) { 92 int minLowRowIndex = mLocations.size() > 0 ? getMinLowRowIndex() : -1; 93 int minLow = minLowRowIndex != -1 ? mRows[minLowRowIndex].low : Integer.MAX_VALUE; 94 for (; rowIndex >=0 ; rowIndex--) { 95 if (itemIndex < 0) { 96 break top_loop; 97 } 98 prependItemToRow(itemIndex--, rowIndex); 99 if (minLowRowIndex == -1) { 100 minLowRowIndex = getMinLowRowIndex(); 101 minLow = mRows[minLowRowIndex].low; 102 } else if (rowIndex != minLowRowIndex) { 103 while (mRows[rowIndex].low > minLow) { 104 if (itemIndex < 0) { 105 break top_loop; 106 } 107 prependItemToRow(itemIndex--, rowIndex); 108 } 109 } 110 } 111 if (mRows[getMaxLowRowIndex()].low <= downTo) { 112 break; 113 } 114 rowIndex = mNumRows - 1; 115 } 116 } 117 118 @Override 119 public final void stripDownTo(int itemIndex) { 120 // because we layout the items in the order that next item is either same row 121 // or next row, so we can easily find the row range by searching items forward and 122 // backward until we see the row is 0 or mNumRow - 1 123 Location loc = getLocation(itemIndex); 124 if (loc == null) { 125 return; 126 } 127 int firstIndex = getFirstIndex(); 128 int lastIndex = getLastIndex(); 129 int row = loc.row; 130 131 int endIndex = itemIndex; 132 int endRow = row; 133 while (endRow < mNumRows - 1 && endIndex < lastIndex) { 134 endIndex++; 135 endRow = getLocation(endIndex).row; 136 } 137 138 int startIndex = itemIndex; 139 int startRow = row; 140 while (startRow > 0 && startIndex > firstIndex) { 141 startIndex--; 142 startRow = getLocation(startIndex).row; 143 } 144 // trim information 145 for (int i = firstIndex; i < startIndex; i++) { 146 removeFirst(); 147 } 148 for (int i = endIndex; i < lastIndex; i++) { 149 removeLast(); 150 } 151 } 152} 153