ObjectAdapter.java revision 0f1fa0dfa946ddc8afb6af26a4dd1a4d01dca10f
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 16import android.database.Observable; 17 18/** 19 * Adapter for leanback activities. Provides access to a data model and is 20 * decoupled from the presentation of the items via {@link PresenterSelector}. 21 */ 22public abstract class ObjectAdapter { 23 24 public static final int NO_ID = -1; 25 26 /** 27 * A DataObserver can be notified when an ObjectAdapter's underlying data 28 * changes. Separate methods provide notifications about different types of 29 * changes. 30 */ 31 public static abstract class DataObserver { 32 /** 33 * Called whenever the ObjectAdapter's data has changed in some manner 34 * outside of the set of changes covered by the other range based change 35 * notification methods. 36 */ 37 public void onChanged() { 38 } 39 40 /** 41 * Called when a range of items in the ObjectAdapter has changed. The 42 * basic ordering and structure of the ObjectAdapter has not changed. 43 * 44 * @param positionStart The position of the first item that changed. 45 * @param itemCount The number of items changed. 46 */ 47 public void onItemRangeChanged(int positionStart, int itemCount) { 48 onChanged(); 49 } 50 51 /** 52 * Called when a range of items is inserted into the ObjectAdapter. 53 * 54 * @param positionStart The position of the first inserted item. 55 * @param itemCount The number of items inserted. 56 */ 57 public void onItemRangeInserted(int positionStart, int itemCount) { 58 onChanged(); 59 } 60 61 /** 62 * Called when a range of items is removed from the ObjectAdapter. 63 * 64 * @param positionStart The position of the first removed item. 65 * @param itemCount The number of items removed. 66 */ 67 public void onItemRangeRemoved(int positionStart, int itemCount) { 68 onChanged(); 69 } 70 } 71 72 private static final class DataObservable extends Observable<DataObserver> { 73 74 public void notifyChanged() { 75 for (int i = mObservers.size() - 1; i >= 0; i--) { 76 mObservers.get(i).onChanged(); 77 } 78 } 79 80 public void notifyItemRangeChanged(int positionStart, int itemCount) { 81 for (int i = mObservers.size() - 1; i >= 0; i--) { 82 mObservers.get(i).onItemRangeChanged(positionStart, itemCount); 83 } 84 } 85 86 public void notifyItemRangeInserted(int positionStart, int itemCount) { 87 for (int i = mObservers.size() - 1; i >= 0; i--) { 88 mObservers.get(i).onItemRangeInserted(positionStart, itemCount); 89 } 90 } 91 92 public void notifyItemRangeRemoved(int positionStart, int itemCount) { 93 for (int i = mObservers.size() - 1; i >= 0; i--) { 94 mObservers.get(i).onItemRangeRemoved(positionStart, itemCount); 95 } 96 } 97 } 98 99 private final DataObservable mObservable = new DataObservable(); 100 private boolean mHasStableIds; 101 private PresenterSelector mPresenterSelector; 102 103 /** 104 * Construct an adapter with the given {@link PresenterSelector}. 105 */ 106 public ObjectAdapter(PresenterSelector presenterSelector) { 107 setPresenterSelector(presenterSelector); 108 } 109 110 /** 111 * Construct an adapter that uses the given {@link Presenter} for all items. 112 */ 113 public ObjectAdapter(Presenter presenter) { 114 setPresenterSelector(new SinglePresenterSelector(presenter)); 115 } 116 117 /** 118 * Construct an adapter. 119 */ 120 public ObjectAdapter() { 121 } 122 123 /** 124 * Set the presenter selector. May not be null. 125 */ 126 public final void setPresenterSelector(PresenterSelector presenterSelector) { 127 if (presenterSelector == null) { 128 throw new IllegalArgumentException("Presenter selector must not be null"); 129 } 130 final boolean update = (mPresenterSelector != null); 131 mPresenterSelector = presenterSelector; 132 if (update) { 133 notifyChanged(); 134 } 135 } 136 137 /** 138 * Returns the presenter selector; 139 */ 140 public final PresenterSelector getPresenterSelector() { 141 return mPresenterSelector; 142 } 143 144 /** 145 * Register a DataObserver for data change notifications. 146 */ 147 public final void registerObserver(DataObserver observer) { 148 mObservable.registerObserver(observer); 149 } 150 151 /** 152 * Unregister a DataObserver for data change notifications. 153 */ 154 public final void unregisterObserver(DataObserver observer) { 155 mObservable.unregisterObserver(observer); 156 } 157 158 /** 159 * Unregister all DataObservers for this ObservableList. 160 */ 161 public final void unregisterAllObservers() { 162 mObservable.unregisterAll(); 163 } 164 165 final protected void notifyItemRangeChanged(int positionStart, int itemCount) { 166 mObservable.notifyItemRangeChanged(positionStart, itemCount); 167 } 168 169 final protected void notifyItemRangeInserted(int positionStart, int itemCount) { 170 mObservable.notifyItemRangeInserted(positionStart, itemCount); 171 } 172 173 final protected void notifyItemRangeRemoved(int positionStart, int itemCount) { 174 mObservable.notifyItemRangeRemoved(positionStart, itemCount); 175 } 176 177 final protected void notifyChanged() { 178 mObservable.notifyChanged(); 179 } 180 181 /** 182 * Indicates whether the item ids are stable across changes to the 183 * underlying data. When this is true, client of Adapter can use 184 * {@link #getId(int)} to correlate objects across changes. 185 */ 186 public final boolean hasStableIds() { 187 return mHasStableIds; 188 } 189 190 /** 191 * Sets whether the item ids are stable across changes to the underlying 192 * data. 193 */ 194 public final void setHasStableIds(boolean hasStableIds) { 195 mHasStableIds = hasStableIds; 196 } 197 198 /** 199 * Returns the {@link Presenter} for the given item from the adapter. 200 */ 201 public final Presenter getPresenter(Object item) { 202 if (mPresenterSelector == null) { 203 throw new IllegalStateException("Presenter selector must not be null"); 204 } 205 return mPresenterSelector.getPresenter(item); 206 } 207 208 /** 209 * Returns the number of items in the adapter. 210 */ 211 public abstract int size(); 212 213 /** 214 * Returns the item for the given position. 215 */ 216 public abstract Object get(int position); 217 218 /** 219 * Returns id for the given position. 220 */ 221 public long getId(int position) { 222 return NO_ID; 223 } 224} 225