Last active
January 20, 2019 08:26
-
-
Save tomergoldst/4620f6ea0fd027cfc85fa3a77ee537c1 to your computer and use it in GitHub Desktop.
An implementation of PagerAdapter for views
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* View Pager Adapter - An implementation of PagerAdapter for views | |
* Simplified implementation which enables access to created view at a specific position | |
* for controlling the view status and force pre creation of a view when necessary | |
* | |
* Created by tomergoldst on 15/11/2018. | |
*/ | |
public abstract class ViewPagerAdapter<T> extends PagerAdapter { | |
private SparseArray<T> mViews = new SparseArray<>(); | |
private final Object mLock = new Object(); | |
/** | |
* Force create view at position | |
* | |
* @param position position | |
* @return view created by createView(int position) | |
*/ | |
public final T forceViewCreation(int position) { | |
return instantiateView(position); | |
} | |
/** | |
* re-instantiate all cached views, this will trigger the abstract {@link #createView(int)} and | |
* {@link #onViewCreated(Object, int)} | |
*/ | |
public final void reInstantiateCachedViews() { | |
synchronized (mLock) { | |
for (int i = 0, N = mViews.size(); i < N; i++) { | |
int key = mViews.keyAt(i); | |
instantiateView(key); | |
} | |
} | |
} | |
/** | |
* Clear cache. Using this operation should follow a call to setAdapter which in turn will call | |
* instantiateItem | |
*/ | |
public final void clearCache() { | |
synchronized (mLock) { | |
mViews.clear(); | |
} | |
} | |
/** | |
* Create view at position | |
* | |
* @param position position | |
* @return view created by createView(int position) | |
*/ | |
private T instantiateView(int position) { | |
synchronized (mLock) { | |
isValidPosition(position); | |
T view = checkNotNull(createView(position)); | |
mViews.put(position, view); | |
onViewCreated(view, position); | |
return view; | |
} | |
} | |
/** | |
* Called after view was created | |
* | |
* @param view created view | |
* @param position position | |
*/ | |
public void onViewCreated(T view, int position) { | |
// Empty implementation | |
} | |
/** | |
* Check if position is valid | |
* | |
* @param position position | |
*/ | |
private void isValidPosition(int position) { | |
if (position < 0 || position > getCount() - 1) { | |
throw new RuntimeException("position " + position + " is not valid, " + | |
"getCount() == " + getCount()); | |
} | |
} | |
/** | |
* Create view at position | |
* | |
* @param position viewpager position | |
* @return DaysPickerView | |
*/ | |
public abstract T createView(int position); | |
/** | |
* get view at position. If view at position doesn't exist create the view | |
* | |
* @param position viewpager position | |
* @return DaysPickerView | |
*/ | |
public final T getViewAtPosition(int position) { | |
synchronized (mLock) { | |
isValidPosition(position); | |
T view = mViews.get(position); | |
if (view == null) { | |
view = instantiateView(position); | |
} | |
return view; | |
} | |
} | |
/** | |
* get cached view at position. If view at position doesn't exist return null | |
* | |
* @param position viewpager position | |
* @return DaysPickerView | |
*/ | |
public final T getCachedViewAtPosition(int position) { | |
synchronized (mLock) { | |
isValidPosition(position); | |
return mViews.get(position); | |
} | |
} | |
/** | |
* @param position requested view position | |
* @return true if mViews contain view on position | |
*/ | |
protected final boolean isViewExist(int position) { | |
synchronized (mLock) { | |
isValidPosition(position); | |
return mViews.get(position) != null; | |
} | |
} | |
@Override | |
abstract public int getCount(); | |
@NotNull | |
@Override | |
public final Object instantiateItem(ViewGroup container, int position) { | |
View view = (View) getViewAtPosition(position); | |
container.addView(view); | |
return view; | |
} | |
@Override | |
public final boolean isViewFromObject(@NotNull View view, @NotNull Object object) { | |
return view == object; | |
} | |
@Override | |
public void destroyItem(@NotNull ViewGroup container, int position, @NotNull Object object) { | |
View view = (View) object; | |
container.removeView(view); | |
removeView(position); | |
} | |
/** | |
* @param position of view to remove | |
*/ | |
private void removeView(int position) { | |
synchronized (mLock) { | |
isValidPosition(position); | |
mViews.remove(position); | |
} | |
} | |
private static <T> T checkNotNull(T reference) { | |
if (reference == null) { | |
throw new NullPointerException(); | |
} else { | |
return reference; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment