1/* 2 * Copyright (C) 2015 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 16import android.support.v4.util.CircularIntArray; 17 18import java.io.PrintWriter; 19 20/** 21 * A Grid with restriction to single row. 22 */ 23class SingleRow extends Grid { 24 25 private final Location mTmpLocation = new Location(0); 26 private Object[] mTmpItem = new Object[1]; 27 28 SingleRow() { 29 setNumRows(1); 30 } 31 32 @Override 33 public final Location getLocation(int index) { 34 // all items are on row 0, share the same Location object. 35 return mTmpLocation; 36 } 37 38 @Override 39 public final void debugPrint(PrintWriter pw) { 40 pw.print("SingleRow<"); 41 pw.print(mFirstVisibleIndex); 42 pw.print(","); 43 pw.print(mLastVisibleIndex); 44 pw.print(">"); 45 pw.println(); 46 } 47 48 int getStartIndexForAppend() { 49 if (mLastVisibleIndex >= 0) { 50 return mLastVisibleIndex + 1; 51 } else if (mStartIndex != START_DEFAULT) { 52 return Math.min(mStartIndex, mProvider.getCount() - 1); 53 } else { 54 return 0; 55 } 56 } 57 58 int getStartIndexForPrepend() { 59 if (mFirstVisibleIndex >= 0) { 60 return mFirstVisibleIndex - 1; 61 } else if (mStartIndex != START_DEFAULT) { 62 return Math.min(mStartIndex, mProvider.getCount() - 1); 63 } else { 64 return mProvider.getCount() - 1; 65 } 66 } 67 68 @Override 69 protected final boolean prependVisibleItems(int toLimit, boolean oneColumnMode) { 70 if (mProvider.getCount() == 0) { 71 return false; 72 } 73 if (!oneColumnMode && checkPrependOverLimit(toLimit)) { 74 return false; 75 } 76 boolean filledOne = false; 77 for (int index = getStartIndexForPrepend(); index >= 0; index--) { 78 int size = mProvider.createItem(index, false, mTmpItem); 79 int edge; 80 if (mFirstVisibleIndex < 0 || mLastVisibleIndex < 0) { 81 edge = mReversedFlow ? Integer.MIN_VALUE : Integer.MAX_VALUE; 82 mLastVisibleIndex = mFirstVisibleIndex = index; 83 } else { 84 if (mReversedFlow) { 85 edge = mProvider.getEdge(index + 1) + mMargin + size; 86 } else { 87 edge = mProvider.getEdge(index + 1) - mMargin - size; 88 } 89 mFirstVisibleIndex = index; 90 } 91 mProvider.addItem(mTmpItem[0], index, size, 0, edge); 92 filledOne = true; 93 if (oneColumnMode || checkPrependOverLimit(toLimit)) { 94 break; 95 } 96 } 97 return filledOne; 98 } 99 100 @Override 101 protected final boolean appendVisibleItems(int toLimit, boolean oneColumnMode) { 102 if (mProvider.getCount() == 0) { 103 return false; 104 } 105 if (!oneColumnMode && checkAppendOverLimit(toLimit)) { 106 // not in one column mode, return immediately if over limit 107 return false; 108 } 109 boolean filledOne = false; 110 for (int index = getStartIndexForAppend(); index < mProvider.getCount(); index++) { 111 int size = mProvider.createItem(index, true, mTmpItem); 112 int edge; 113 if (mFirstVisibleIndex < 0 || mLastVisibleIndex< 0) { 114 edge = mReversedFlow ? Integer.MAX_VALUE : Integer.MIN_VALUE; 115 mLastVisibleIndex = mFirstVisibleIndex = index; 116 } else { 117 if (mReversedFlow) { 118 edge = mProvider.getEdge(index - 1) - mProvider.getSize(index - 1) - mMargin; 119 } else { 120 edge = mProvider.getEdge(index - 1) + mProvider.getSize(index - 1) + mMargin; 121 } 122 mLastVisibleIndex = index; 123 } 124 mProvider.addItem(mTmpItem[0], index, size, 0, edge); 125 filledOne = true; 126 if (oneColumnMode || checkAppendOverLimit(toLimit)) { 127 break; 128 } 129 } 130 return filledOne; 131 } 132 133 @Override 134 public final CircularIntArray[] getItemPositionsInRows(int startPos, int endPos) { 135 // all items are on the same row: 136 mTmpItemPositionsInRows[0].clear(); 137 mTmpItemPositionsInRows[0].addLast(startPos); 138 mTmpItemPositionsInRows[0].addLast(endPos); 139 return mTmpItemPositionsInRows; 140 } 141 142 @Override 143 protected final int findRowMin(boolean findLarge, int indexLimit, int[] indices) { 144 if (indices != null) { 145 indices[0] = 0; 146 indices[1] = indexLimit; 147 } 148 return mReversedFlow ? mProvider.getEdge(indexLimit) - mProvider.getSize(indexLimit) 149 : mProvider.getEdge(indexLimit); 150 } 151 152 @Override 153 protected final int findRowMax(boolean findLarge, int indexLimit, int[] indices) { 154 if (indices != null) { 155 indices[0] = 0; 156 indices[1] = indexLimit; 157 } 158 return mReversedFlow ? mProvider.getEdge(indexLimit) 159 : mProvider.getEdge(indexLimit) + mProvider.getSize(indexLimit); 160 } 161 162} 163