1717import java .util .WeakHashMap ;
1818
1919/**
20- * A PagerAdapter built to handle dynamic deletion of children with animations. Use discardView()
20+ * A PagerAdapter for ViewPager that keeps a cache of ViewHolders. The data set can be updated
21+ * dynamically and items can be removed with animations if desired. Use discardView()
2122 * to start a dismissal animation. collapseViewsIn() is also exposed if you wish to use gestures
22- * to delete items (this gets used in DynamicViewPager, for example).
23+ * to delete items (ex. fling a View off the screen, then call collapseViewsIn(view) to start the
24+ * collapsing animation - this is done in DynamicViewPager).
2325 *
2426 * @author jacobamuchow@gmail.com (Jacob Muchow)
2527 */
@@ -45,19 +47,19 @@ public ViewHolder(View view) {
4547 }
4648 }
4749
48- private WeakHashMap <Integer , VH > children = new WeakHashMap <>();
49- private boolean isChildAnimating = false ;
50+ private WeakHashMap <Integer , VH > viewHolderCache = new WeakHashMap <>();
51+ private boolean isViewAnimating = false ;
5052
5153 @ Nullable private Callbacks callbacks ;
5254
5355 @ Override
54- public final Object instantiateItem (ViewGroup container , int position ) {
56+ public Object instantiateItem (ViewGroup container , int position ) {
5557
5658 VH viewHolder = null ;
5759 int viewType = getViewType (position );
5860
59- if (children .containsKey (position )) {
60- viewHolder = children .get (position );
61+ if (viewHolderCache .containsKey (position )) {
62+ viewHolder = viewHolderCache .get (position );
6163
6264 if (viewHolder .viewType != viewType ) {
6365 destroyItem (container , position , viewHolder .view );
@@ -68,7 +70,7 @@ public final Object instantiateItem(ViewGroup container, int position) {
6870 if (viewHolder == null ) {
6971 viewHolder = onCreateViewHolder (container , position , viewType );
7072 viewHolder .viewType = viewType ;
71- children .put (position , viewHolder );
73+ viewHolderCache .put (position , viewHolder );
7274 }
7375
7476 onBindViewHolder (viewHolder , position );
@@ -82,13 +84,16 @@ public final Object instantiateItem(ViewGroup container, int position) {
8284 public abstract void onBindViewHolder (VH viewHolder , int position );
8385
8486 @ Override
85- public final int getItemPosition (Object object ) {
87+ public int getItemPosition (Object object ) {
8688 return POSITION_NONE ;
8789 }
8890
91+ /**
92+ * Removes a View from its container and the cache
93+ */
8994 @ Override
90- public final void destroyItem (ViewGroup container , int position , Object view ) {
91- children .remove (position );
95+ public void destroyItem (ViewGroup container , int position , Object view ) {
96+ viewHolderCache .remove (position );
9297 container .removeView ((View ) view );
9398 }
9499
@@ -101,6 +106,19 @@ public int getViewType(int position) {
101106 return DEFAULT_VIEW_TYPE ;
102107 }
103108
109+ /**
110+ * A non-destructive way to "notify data set changed". By default, when {@link #notifyDataSetChanged()}
111+ * is called, the ViewPager will destroy all the Views and recreate them if {@link #getItemPosition(Object)}
112+ * returns POSITION_NONE. This may not be desirable behavior in some cases. This method will call
113+ * {@link #onBindViewHolder(ViewHolder, int)} on each of the cached ViewHolders in order to
114+ * update them without destroying the Views.
115+ */
116+ public void updateViews () {
117+ for (Map .Entry <Integer , VH > entry : viewHolderCache .entrySet ()) {
118+ onBindViewHolder (entry .getValue (), entry .getKey ());
119+ }
120+ }
121+
104122 /**
105123 * Returns a View for the position provided if cached. Take a look at
106124 * {@link #getViewHolderAt(int)} or more details.
@@ -111,7 +129,6 @@ public View getViewAt(int position) {
111129 return viewHolder == null ? null : viewHolder .view ;
112130 }
113131
114-
115132 /**
116133 * Returns a ViewHolder for the position provided if cached.
117134 *
@@ -120,7 +137,7 @@ public View getViewAt(int position) {
120137 */
121138 @ Nullable
122139 public VH getViewHolderAt (int position ) {
123- return children .get (position );
140+ return viewHolderCache .get (position );
124141 }
125142
126143 /**
@@ -138,7 +155,7 @@ public int getPositionForView(@Nullable View view) {
138155 return NO_POSITION ;
139156 }
140157
141- for (Map .Entry <Integer , VH > entry : children .entrySet ()) {
158+ for (Map .Entry <Integer , VH > entry : viewHolderCache .entrySet ()) {
142159 if (entry .getValue ().view .equals (view )) {
143160 return entry .getKey ();
144161
@@ -148,21 +165,28 @@ public int getPositionForView(@Nullable View view) {
148165 return NO_POSITION ;
149166 }
150167
168+ /**
169+ * @return the cache of ViewHolders
170+ */
171+ protected WeakHashMap <Integer , VH > getViewHolderCache () {
172+ return viewHolderCache ;
173+ }
174+
151175 /**
152176 * You may want to use this to stop gesture detection or other UI elements during animation.
153177 *
154178 * @return true if a child is in the middle of animating.
155179 */
156- public boolean isChildAnimating () {
157- return isChildAnimating ;
180+ public boolean isViewAnimating () {
181+ return isViewAnimating ;
158182 }
159183
160184 /**
161185 * This is only used as a state holder. The DynamicPagerAdapter does not change behavior
162186 * due to this variable.
163187 */
164- public void setChildAnimating (boolean childAnimating ) {
165- isChildAnimating = childAnimating ;
188+ public void setViewAnimating (boolean viewAnimating ) {
189+ isViewAnimating = viewAnimating ;
166190 }
167191
168192 /**
@@ -192,14 +216,14 @@ public boolean discardView(@Nullable final View view) {
192216 return false ;
193217 }
194218
195- isChildAnimating = startDiscardAnimation (view , new SimpleAnimationListener () {
219+ isViewAnimating = startDiscardAnimation (view , new SimpleAnimationListener () {
196220 @ Override
197221 public void onAnimationEnd (Animation animation ) {
198222 collapseViewsIn (view );
199223 }
200224 });
201225
202- return isChildAnimating ;
226+ return isViewAnimating ;
203227 }
204228
205229 /**
@@ -245,7 +269,7 @@ public boolean collapseViewsIn(@Nullable final View view) {
245269 */
246270 if (position == NO_POSITION ) {
247271 if (callbacks != null ) {
248- isChildAnimating = false ;
272+ isViewAnimating = false ;
249273 callbacks .onDiscardFinished (position , view );
250274 }
251275 return false ;
@@ -267,7 +291,7 @@ public boolean collapseViewsIn(@Nullable final View view) {
267291 */
268292 if (nextView == null ) {
269293 if (callbacks != null ) {
270- isChildAnimating = false ;
294+ isViewAnimating = false ;
271295 callbacks .onDiscardFinished (position , view );
272296 }
273297 return false ;
@@ -289,7 +313,7 @@ public void onAnimationEnd(Animation animation) {
289313 new Handler (Looper .getMainLooper ()).post (new Runnable () {
290314 @ Override
291315 public void run () {
292- isChildAnimating = false ;
316+ isViewAnimating = false ;
293317 callbacks .onDiscardFinished (pos , view );
294318 }
295319 });
@@ -301,7 +325,7 @@ public void run() {
301325 startFarNextViewAnimation (position , view , nextView , farNextView );
302326 }
303327
304- isChildAnimating = true ;
328+ isViewAnimating = true ;
305329 return true ;
306330 }
307331
0 commit comments