- Post number 1
- Post number 2
- Post number 3
- Post number 4
It turned out that I needed the same method in order to finish my decorated ViewPager. I also wanted to avoid the coupling between adapter and the pager itself when I implemented this method and all currently proposed solutions involved such to one extent or the other. It seems I was able to achieve what I was aiming at.
The working solution
How did I solve it? I basically build over my decorator solution, so be sure to read about it before you can fully understand my approach. You can also see the source of this solution here (the code was built to demonstrate the decorator, but the getCurrentView is also featured in it).What I did: I wrapped the adapters being set to my decorated view pager with a little extension letting me keep track of the current view. This extension is placed transparantely to the user of the decorated view pager:
@Override public void setAdapter(PagerAdapter adapter) { super.setAdapter(new DecoratedPagerAdapter(this, adapter)); } @Override public PagerAdapter getAdapter() { DecoratedPagerAdapter adapter = getDecoratedPagerAdapter(); return adapter.getPagerAdapter(); }And now the simple implementation of the `DecoratedPagerAdapter`:
class DecoratedPagerAdapter extends PagerAdapter { private PagerAdapter pagerAdapter; /** Stores the views in the actual position of the adapter. */ private SparseArrayI basically cache the views loaded in the view pager in a sparsed array. Item is inserted when it is intitialized by the lazy-loading view pager and is removed from the cache immediately after it is removed from the lazy loading-view pager. I believe this implementation should be optimal even for view pagers with windows of the size of dozens. Finally hte base decoration class (in my case ViewPagerDecoration) defines the following method:instantiatedViewsSparsedArray; private ViewPager viewPager; public DecoratedPagerAdapter(ViewPager viewPager, PagerAdapter decoratedPagerAdapter) { this.pagerAdapter = decoratedPagerAdapter; decoratedPagerAdapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { notifyDataSetChanged(); } }); this.viewPager = viewPager; this.instantiatedViewsSparsedArray = new SparseArray (); } @Override public Object instantiateItem(ViewGroup container, int position) { Object object = pagerAdapter.instantiateItem(container, position); ViewPager viewPager = (ViewPager) container; int childCount = viewPager.getChildCount(); for (int i = 0; i < childCount; i++) { View child = viewPager.getChildAt(i); if (isViewFromObject(child, object)) { instantiatedViewsSparsedArray.put(position, child); break; } } return object; } @Override public int getItemPosition(Object object) { int childCount = viewPager.getChildCount(); for (int i = 0; i < childCount; i++) { View child = viewPager.getChildAt(i); if (isViewFromObject(child, object)) { return i; } } return POSITION_NONE; } /** * @param position the position in the adapter of the view we are interested in. * @return The view at position {@code position} in the adapter or null if it has not been initialized. */ View getViewAtPosition(int position) { return instantiatedViewsSparsedArray.get(position); } @Override public void destroyItem(ViewGroup container, int position, Object object) { ((ViewPager) container).removeView((View) object); instantiatedViewsSparsedArray.remove(position); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return pagerAdapter.isViewFromObject(arg0, arg1); } @Override public int getCount() { return pagerAdapter.getCount(); } /** * The method is deliberately package-protected. * * @return The pager adapter that is wrapped with current view tracking pager adapter. */ PagerAdapter getPagerAdapter() { return pagerAdapter; } }
/** Returns the index'th child of the decorated {@link ViewPager} */ protected View getCurrentView() { DecoratedPagerAdapter pagerAdapter = viewPager.getDecoratedPagerAdapter(); return pagerAdapter.getViewAtPosition(getCurrentItem()); }In the source I link to the method is defined as protected and with decorator solution it seems logical to me that this current view would be needed only in extensions. Still, if it is not your case I believe you need small code change to make the method available in the DecoratedViewPager instead. I hope you enjoy this solution and we finally get a fully documented solution of this common question in the Android world. Enjoy!
Няма коментари:
Публикуване на коментар