ObjectAdapter.java revision 13d1515a1edd63f26ad7f3c9c7471d0969900190
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 class DataObservable extends Observable<DataObserver> { 73 public boolean hasObservers() { 74 return !mObservers.isEmpty(); 75 } 76 77 public void notifyChanged() { 78 for (int i = mObservers.size() - 1; i >= 0; i--) { 79 mObservers.get(i).onChanged(); 80 } 81 } 82 83 public void notifyItemRangeChanged(int positionStart, int itemCount) { 84 for (int i = mObservers.size() - 1; i >= 0; i--) { 85 mObservers.get(i).onItemRangeChanged(positionStart, itemCount); 86 } 87 } 88 89 public void notifyItemRangeInserted(int positionStart, int itemCount) { 90 for (int i = mObservers.size() - 1; i >= 0; i--) { 91 mObservers.get(i).onItemRangeInserted(positionStart, itemCount); 92 } 93 } 94 95 public void notifyItemRangeRemoved(int positionStart, int itemCount) { 96 for (int i = mObservers.size() - 1; i >= 0; i--) { 97 mObservers.get(i).onItemRangeRemoved(positionStart, itemCount); 98 } 99 } 100 } 101 102 private final DataObservable mObservable = new DataObservable(); 103 private boolean mHasStableIds; 104 private PresenterSelector mPresenterSelector; 105 106 /** 107 * Construct an adapter with the given {@link PresenterSelector}. 108 */ 109 public ObjectAdapter(PresenterSelector presenterSelector) { 110 setPresenterSelector(presenterSelector); 111 } 112 113 /** 114 * Construct an adapter that uses the given {@link Presenter} for all items. 115 */ 116 public ObjectAdapter(Presenter presenter) { 117 setPresenterSelector(new SinglePresenterSelector(presenter)); 118 } 119 120 /** 121 * Construct an adapter. 122 */ 123 public ObjectAdapter() { 124 } 125 126 /** 127 * Set the presenter selector. May not be null. 128 */ 129 public void setPresenterSelector(PresenterSelector presenterSelector) { 130 if (presenterSelector == null) { 131 throw new IllegalArgumentException("Presenter selector must not be null"); 132 } 133 final boolean update = (mPresenterSelector != null); 134 mPresenterSelector = presenterSelector; 135 if (update) { 136 notifyChanged(); 137 } 138 } 139 140 /** 141 * Returns the presenter selector; 142 */ 143 public PresenterSelector getPresenterSelector() { 144 return mPresenterSelector; 145 } 146 147 /** 148 * Register a DataObserver for data change notifications. 149 */ 150 public void registerObserver(DataObserver observer) { 151 mObservable.registerObserver(observer); 152 } 153 154 /** 155 * Unregister a DataObserver for data change notifications. 156 */ 157 public void unregisterObserver(DataObserver observer) { 158 mObservable.unregisterObserver(observer); 159 } 160 161 /** 162 * Unregister all DataObservers for this ObservableList. 163 */ 164 public void unregisterAllObservers() { 165 mObservable.unregisterAll(); 166 } 167 168 final protected void notifyItemRangeChanged(int positionStart, int itemCount) { 169 mObservable.notifyItemRangeChanged(positionStart, itemCount); 170 } 171 172 final protected void notifyItemRangeInserted(int positionStart, int itemCount) { 173 mObservable.notifyItemRangeInserted(positionStart, itemCount); 174 } 175 176 final protected void notifyItemRangeRemoved(int positionStart, int itemCount) { 177 mObservable.notifyItemRangeRemoved(positionStart, itemCount); 178 } 179 180 final protected void notifyChanged() { 181 mObservable.notifyChanged(); 182 } 183 184 /** 185 * Indicates whether the item ids are stable across changes to the 186 * underlying data. When this is true, client of Adapter can use 187 * {@link #getId(int)} to correlate objects across changes. 188 */ 189 public boolean hasStableIds() { 190 return mHasStableIds; 191 } 192 193 /** 194 * Sets whether the item ids are stable across changes to the underlying 195 * data. 196 */ 197 public void setHasStableIds(boolean hasStableIds) { 198 mHasStableIds = hasStableIds; 199 } 200 201 /** 202 * Returns the {@link Presenter} for the given item from the adapter. 203 */ 204 public Presenter getPresenter(Object item) { 205 if (mPresenterSelector == null) { 206 throw new IllegalStateException("Presenter selector must not be null"); 207 } 208 return mPresenterSelector.getPresenter(item); 209 } 210 211 /** 212 * Returns the number of items in the adapter. 213 */ 214 public abstract int size(); 215 216 /** 217 * Returns the item for the given position. 218 */ 219 public abstract Object get(int position); 220 221 /** 222 * Returns id for the given position. 223 */ 224 public long getId(int position) { 225 return NO_ID; 226 } 227} 228