blob: 43000302c2f3a0b4a5a974c7e73a03776787564d [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.arch.paging;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import java.util.ArrayList;
import java.util.List;
/**
* NullPaddedList is a simple list, with optional null padding on the beginning and end.
*
* @param <Type> The type of the entries in the list.
*
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class NullPaddedList<Type> extends PagedList<Type> {
List<Type> mList;
int mTrailingNullCount;
int mLeadingNullCount;
int mPositionOffset;
// track the items prepended/appended since the PagedList was initialized
int mNumberPrepended;
int mNumberAppended;
NullPaddedList() {
}
@Override
public String toString() {
return "NullPaddedList " + mLeadingNullCount
+ ", " + mList.size()
+ ", " + mTrailingNullCount;
}
/**
* Create a static, immutable NullPaddedList with the specified list,
*
* @param leadingNullCount Number of empty items in advance of the passed list.
* @param list List of items.
* @param trailingNullCount Number of empty items following the passed list.
*/
NullPaddedList(int leadingNullCount, List<Type> list, int trailingNullCount) {
if (leadingNullCount < 0 || trailingNullCount < 0) {
throw new IllegalArgumentException("leading/trailing null count must be non-negative");
}
if (list == null) {
throw new IllegalArgumentException("list must be non-null");
}
mList = list;
mLeadingNullCount = leadingNullCount;
mTrailingNullCount = trailingNullCount;
}
NullPaddedList(int leadingNullCount, int totalCount, List<Type> list) {
if (list == null) {
throw new IllegalArgumentException("list must be non-null");
}
int trailingNullCount = totalCount - (leadingNullCount) - list.size();
mList = list;
mLeadingNullCount = leadingNullCount;
mTrailingNullCount = trailingNullCount;
}
NullPaddedList(int positionOffset, List<Type> list) {
if (list == null) {
throw new IllegalArgumentException("list must be non-null");
}
mList = list;
mPositionOffset = positionOffset;
}
/**
* Create a copy of the passed NullPaddedList.
*
* @param other Other list to copy.
*/
NullPaddedList(NullPaddedList<Type> other) {
mLeadingNullCount = other.getLeadingNullCount();
mList = other.isImmutable() ? other.mList : new ArrayList<>(other.mList);
mTrailingNullCount = other.getTrailingNullCount();
mNumberPrepended = other.getNumberPrepended();
mNumberAppended = other.getNumberAppended();
}
// --------------- PagedList API ---------------
@Override
public Type get(int index) {
if (index < 0 || index >= size()) {
throw new IndexOutOfBoundsException();
}
index -= mLeadingNullCount;
if (index < 0) {
return null;
}
if (index >= mList.size()) {
return null;
}
return mList.get(index);
}
@Override
public void loadAround(int index) {
// do nothing - immutable, so no fetching will be done
}
@Override
public final int size() {
return getLoadedCount() + getLeadingNullCount() + getTrailingNullCount();
}
public boolean isImmutable() {
return true;
}
@Override
public PagedList<Type> snapshot() {
if (isImmutable()) {
return this;
}
return new NullPaddedList<>(this);
}
@Override
boolean isContiguous() {
return true;
}
@Override
public void addWeakCallback(@Nullable PagedList<Type> previousSnapshot,
@NonNull Callback callback) {
// no op, immutable
}
@Override
public void removeWeakCallback(Callback callback) {
// no op, immutable
}
// --------------- Contiguous API ---------------
@Override
public int getPositionOffset() {
return mPositionOffset;
}
/**
* Number of loaded items. This does not account for leading or trailing null padding.
*
* @return Number of loaded items.
*/
public int getLoadedCount() {
return mList.size();
}
/**
* Number of empty, unloaded items ahead of the loaded item region.
*
* @return Number of nulls before the loaded list.
*/
public int getLeadingNullCount() {
return mLeadingNullCount;
}
/**
* Number of empty, unloaded items behind the loaded item region.
*
* @return Number of nulls after the loaded list.
*/
public int getTrailingNullCount() {
return mTrailingNullCount;
}
int getNumberPrepended() {
return mNumberPrepended;
}
int getNumberAppended() {
return mNumberAppended;
}
}