• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.support.v4.view;
18 
19 import android.database.DataSetObservable;
20 import android.database.DataSetObserver;
21 import android.os.Parcelable;
22 import android.view.View;
23 import android.view.ViewGroup;
24 
25 /**
26  * Base class providing the adapter to populate pages inside of
27  * a {@link ViewPager}.  You will most likely want to use a more
28  * specific implementation of this, such as
29  * {@link android.support.v4.app.FragmentPagerAdapter} or
30  * {@link android.support.v4.app.FragmentStatePagerAdapter}.
31  *
32  * <p>When you implement a PagerAdapter, you must override the following methods
33  * at minimum:</p>
34  * <ul>
35  * <li>{@link #instantiateItem(ViewGroup, int)}</li>
36  * <li>{@link #destroyItem(ViewGroup, int, Object)}</li>
37  * <li>{@link #getCount()}</li>
38  * <li>{@link #isViewFromObject(View, Object)}</li>
39  * </ul>
40  *
41  * <p>PagerAdapter is more general than the adapters used for
42  * {@link android.widget.AdapterView AdapterViews}. Instead of providing a
43  * View recycling mechanism directly ViewPager uses callbacks to indicate the
44  * steps taken during an update. A PagerAdapter may implement a form of View
45  * recycling if desired or use a more sophisticated method of managing page
46  * Views such as Fragment transactions where each page is represented by its
47  * own Fragment.</p>
48  *
49  * <p>ViewPager associates each page with a key Object instead of working with
50  * Views directly. This key is used to track and uniquely identify a given page
51  * independent of its position in the adapter. A call to the PagerAdapter method
52  * {@link #startUpdate(ViewGroup)} indicates that the contents of the ViewPager
53  * are about to change. One or more calls to {@link #instantiateItem(ViewGroup, int)}
54  * and/or {@link #destroyItem(ViewGroup, int, Object)} will follow, and the end
55  * of an update will be signaled by a call to {@link #finishUpdate(ViewGroup)}.
56  * By the time {@link #finishUpdate(ViewGroup) finishUpdate} returns the views
57  * associated with the key objects returned by
58  * {@link #instantiateItem(ViewGroup, int) instantiateItem} should be added to
59  * the parent ViewGroup passed to these methods and the views associated with
60  * the keys passed to {@link #destroyItem(ViewGroup, int, Object) destroyItem}
61  * should be removed. The method {@link #isViewFromObject(View, Object)} identifies
62  * whether a page View is associated with a given key object.</p>
63  *
64  * <p>A very simple PagerAdapter may choose to use the page Views themselves
65  * as key objects, returning them from {@link #instantiateItem(ViewGroup, int)}
66  * after creation and adding them to the parent ViewGroup. A matching
67  * {@link #destroyItem(ViewGroup, int, Object)} implementation would remove the
68  * View from the parent ViewGroup and {@link #isViewFromObject(View, Object)}
69  * could be implemented as <code>return view == object;</code>.</p>
70  *
71  * <p>PagerAdapter supports data set changes. Data set changes must occur on the
72  * main thread and must end with a call to {@link #notifyDataSetChanged()} similar
73  * to AdapterView adapters derived from {@link android.widget.BaseAdapter}. A data
74  * set change may involve pages being added, removed, or changing position. The
75  * ViewPager will keep the current page active provided the adapter implements
76  * the method {@link #getItemPosition(Object)}.</p>
77  */
78 public abstract class PagerAdapter {
79     private final DataSetObservable mObservable = new DataSetObservable();
80     private DataSetObserver mViewPagerObserver;
81 
82     public static final int POSITION_UNCHANGED = -1;
83     public static final int POSITION_NONE = -2;
84 
85     /**
86      * Return the number of views available.
87      */
getCount()88     public abstract int getCount();
89 
90     /**
91      * Called when a change in the shown pages is going to start being made.
92      * @param container The containing View which is displaying this adapter's
93      * page views.
94      */
startUpdate(ViewGroup container)95     public void startUpdate(ViewGroup container) {
96         startUpdate((View) container);
97     }
98 
99     /**
100      * Create the page for the given position.  The adapter is responsible
101      * for adding the view to the container given here, although it only
102      * must ensure this is done by the time it returns from
103      * {@link #finishUpdate(ViewGroup)}.
104      *
105      * @param container The containing View in which the page will be shown.
106      * @param position The page position to be instantiated.
107      * @return Returns an Object representing the new page.  This does not
108      * need to be a View, but can be some other container of the page.
109      */
instantiateItem(ViewGroup container, int position)110     public Object instantiateItem(ViewGroup container, int position) {
111         return instantiateItem((View) container, position);
112     }
113 
114     /**
115      * Remove a page for the given position.  The adapter is responsible
116      * for removing the view from its container, although it only must ensure
117      * this is done by the time it returns from {@link #finishUpdate(ViewGroup)}.
118      *
119      * @param container The containing View from which the page will be removed.
120      * @param position The page position to be removed.
121      * @param object The same object that was returned by
122      * {@link #instantiateItem(View, int)}.
123      */
destroyItem(ViewGroup container, int position, Object object)124     public void destroyItem(ViewGroup container, int position, Object object) {
125         destroyItem((View) container, position, object);
126     }
127 
128     /**
129      * Called to inform the adapter of which item is currently considered to
130      * be the "primary", that is the one show to the user as the current page.
131      *
132      * @param container The containing View from which the page will be removed.
133      * @param position The page position that is now the primary.
134      * @param object The same object that was returned by
135      * {@link #instantiateItem(View, int)}.
136      */
setPrimaryItem(ViewGroup container, int position, Object object)137     public void setPrimaryItem(ViewGroup container, int position, Object object) {
138         setPrimaryItem((View) container, position, object);
139     }
140 
141     /**
142      * Called when the a change in the shown pages has been completed.  At this
143      * point you must ensure that all of the pages have actually been added or
144      * removed from the container as appropriate.
145      * @param container The containing View which is displaying this adapter's
146      * page views.
147      */
finishUpdate(ViewGroup container)148     public void finishUpdate(ViewGroup container) {
149         finishUpdate((View) container);
150     }
151 
152     /**
153      * Called when a change in the shown pages is going to start being made.
154      * @param container The containing View which is displaying this adapter's
155      * page views.
156      *
157      * @deprecated Use {@link #startUpdate(ViewGroup)}
158      */
159     @Deprecated
startUpdate(View container)160     public void startUpdate(View container) {
161     }
162 
163     /**
164      * Create the page for the given position.  The adapter is responsible
165      * for adding the view to the container given here, although it only
166      * must ensure this is done by the time it returns from
167      * {@link #finishUpdate(ViewGroup)}.
168      *
169      * @param container The containing View in which the page will be shown.
170      * @param position The page position to be instantiated.
171      * @return Returns an Object representing the new page.  This does not
172      * need to be a View, but can be some other container of the page.
173      *
174      * @deprecated Use {@link #instantiateItem(ViewGroup, int)}
175      */
176     @Deprecated
instantiateItem(View container, int position)177     public Object instantiateItem(View container, int position) {
178         throw new UnsupportedOperationException(
179                 "Required method instantiateItem was not overridden");
180     }
181 
182     /**
183      * Remove a page for the given position.  The adapter is responsible
184      * for removing the view from its container, although it only must ensure
185      * this is done by the time it returns from {@link #finishUpdate(View)}.
186      *
187      * @param container The containing View from which the page will be removed.
188      * @param position The page position to be removed.
189      * @param object The same object that was returned by
190      * {@link #instantiateItem(View, int)}.
191      *
192      * @deprecated Use {@link #destroyItem(ViewGroup, int, Object)}
193      */
194     @Deprecated
destroyItem(View container, int position, Object object)195     public void destroyItem(View container, int position, Object object) {
196         throw new UnsupportedOperationException("Required method destroyItem was not overridden");
197     }
198 
199     /**
200      * Called to inform the adapter of which item is currently considered to
201      * be the "primary", that is the one show to the user as the current page.
202      *
203      * @param container The containing View from which the page will be removed.
204      * @param position The page position that is now the primary.
205      * @param object The same object that was returned by
206      * {@link #instantiateItem(View, int)}.
207      *
208      * @deprecated Use {@link #setPrimaryItem(ViewGroup, int, Object)}
209      */
210     @Deprecated
setPrimaryItem(View container, int position, Object object)211     public void setPrimaryItem(View container, int position, Object object) {
212     }
213 
214     /**
215      * Called when the a change in the shown pages has been completed.  At this
216      * point you must ensure that all of the pages have actually been added or
217      * removed from the container as appropriate.
218      * @param container The containing View which is displaying this adapter's
219      * page views.
220      *
221      * @deprecated Use {@link #finishUpdate(ViewGroup)}
222      */
223     @Deprecated
finishUpdate(View container)224     public void finishUpdate(View container) {
225     }
226 
227     /**
228      * Determines whether a page View is associated with a specific key object
229      * as returned by {@link #instantiateItem(ViewGroup, int)}. This method is
230      * required for a PagerAdapter to function properly.
231      *
232      * @param view Page View to check for association with <code>object</code>
233      * @param object Object to check for association with <code>view</code>
234      * @return true if <code>view</code> is associated with the key object <code>object</code>
235      */
isViewFromObject(View view, Object object)236     public abstract boolean isViewFromObject(View view, Object object);
237 
238     /**
239      * Save any instance state associated with this adapter and its pages that should be
240      * restored if the current UI state needs to be reconstructed.
241      *
242      * @return Saved state for this adapter
243      */
saveState()244     public Parcelable saveState() {
245         return null;
246     }
247 
248     /**
249      * Restore any instance state associated with this adapter and its pages
250      * that was previously saved by {@link #saveState()}.
251      *
252      * @param state State previously saved by a call to {@link #saveState()}
253      * @param loader A ClassLoader that should be used to instantiate any restored objects
254      */
restoreState(Parcelable state, ClassLoader loader)255     public void restoreState(Parcelable state, ClassLoader loader) {
256     }
257 
258     /**
259      * Called when the host view is attempting to determine if an item's position
260      * has changed. Returns {@link #POSITION_UNCHANGED} if the position of the given
261      * item has not changed or {@link #POSITION_NONE} if the item is no longer present
262      * in the adapter.
263      *
264      * <p>The default implementation assumes that items will never
265      * change position and always returns {@link #POSITION_UNCHANGED}.
266      *
267      * @param object Object representing an item, previously returned by a call to
268      *               {@link #instantiateItem(View, int)}.
269      * @return object's new position index from [0, {@link #getCount()}),
270      *         {@link #POSITION_UNCHANGED} if the object's position has not changed,
271      *         or {@link #POSITION_NONE} if the item is no longer present.
272      */
getItemPosition(Object object)273     public int getItemPosition(Object object) {
274         return POSITION_UNCHANGED;
275     }
276 
277     /**
278      * This method should be called by the application if the data backing this adapter has changed
279      * and associated views should update.
280      */
notifyDataSetChanged()281     public void notifyDataSetChanged() {
282         synchronized (this) {
283             if (mViewPagerObserver != null) {
284                 mViewPagerObserver.onChanged();
285             }
286         }
287         mObservable.notifyChanged();
288     }
289 
290     /**
291      * Register an observer to receive callbacks related to the adapter's data changing.
292      *
293      * @param observer The {@link android.database.DataSetObserver} which will receive callbacks.
294      */
registerDataSetObserver(DataSetObserver observer)295     public void registerDataSetObserver(DataSetObserver observer) {
296         mObservable.registerObserver(observer);
297     }
298 
299     /**
300      * Unregister an observer from callbacks related to the adapter's data changing.
301      *
302      * @param observer The {@link android.database.DataSetObserver} which will be unregistered.
303      */
unregisterDataSetObserver(DataSetObserver observer)304     public void unregisterDataSetObserver(DataSetObserver observer) {
305         mObservable.unregisterObserver(observer);
306     }
307 
setViewPagerObserver(DataSetObserver observer)308     void setViewPagerObserver(DataSetObserver observer) {
309         synchronized (this) {
310             mViewPagerObserver = observer;
311         }
312     }
313 
314     /**
315      * This method may be called by the ViewPager to obtain a title string
316      * to describe the specified page. This method may return null
317      * indicating no title for this page. The default implementation returns
318      * null.
319      *
320      * @param position The position of the title requested
321      * @return A title for the requested page
322      */
getPageTitle(int position)323     public CharSequence getPageTitle(int position) {
324         return null;
325     }
326 
327     /**
328      * Returns the proportional width of a given page as a percentage of the
329      * ViewPager's measured width from (0.f-1.f]
330      *
331      * @param position The position of the page requested
332      * @return Proportional width for the given page position
333      */
getPageWidth(int position)334     public float getPageWidth(int position) {
335         return 1.f;
336     }
337 }
338