Android. support. v4.view. How does ViewPager dynamically change the display content?
Look at a simple piece of code and display two textviews in a pager.
List
items = new ArrayList
();adapter = new MyPagerAdapter();
TextView TV = new TextView (getActivity (); TV. setText (first page); items. add (TV); TV = new TextView (getActivity (); TV. setText (second page); items. add (TV); pager. setAdapter (adapter );
Adapter code
class MyPagerAdapter extends PagerAdapter{@Overridepublic Object instantiateItem(ViewGroup container, int position) {View layout = items.get(position);container.addView(layout);return layout;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {View layout = items.get(position);container.removeView(layout);}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic int getCount() {return items.size();}@Overridepublic int getItemPosition(Object object) {// TODO Auto-generated method stubreturn super.getItemPosition(object);}}
The code runs normally, and the left and right slides are OK.
Well, now the demand is coming. I need to remove "first page" and "second page", and then add two textviews, namely "Third page" and "fourth page ", the following code is written according to common sense:
Items. clear (); TextView TV = new TextView (getActivity (); TV. setText (page 3); items. add (TV); TV = new TextView (getActivity (); TV. setText (page 4); items. add (TV); adapter. notifyDataSetChanged ();
When using ListView, we can change the data of the data source and notify adpater to update the data. However, ViewPager does not work properly. After the code is executed, no changes have been made.
Let's see if ViewPager needs to clear the original attempt.
pager.removeAllViews();
Run it again. It's okay. It's blank. It's useless. It's really clean!
What's the reason?GetItemPosition,Let me see what the ViewPager Adapter does when it changes. When the Adapter executes notifyDataSetChanged, The dataSetChanged method of ViewPager is triggered. The following is the source code ,:
Void dataSetChanged () {// This method only gets called if our observer is attached, so mAdapter is non-null. final int adapterCount = mAdapter. getCount (); mExpectedAdapterCount = adapterCount; boolean needPopulate = mItems. size () <mOffscreenPageLimit * 2 + 1 & mItems. size () <adapterCount; int newCurrItem = mCurItem; boolean isUpdating = false; for (int I = 0; I <mItems. size (); I ++) {final Ite MInfo ii = mItems. get (I); final int newPos = mAdapter. getItemPosition (ii. object); // read this sentence, if it is PagerAdapter. POSITION_UNCHANGED flag, which is returned directly without any processing. if (newPos = PagerAdapter. POSITION_UNCHANGED) {continue;} // only PagerAdapter is returned. if (newPos = PagerAdapter. POSITION_NONE) {// clear mItems from the data source first. remove (I); I --; if (! IsUpdating) {mAdapter. startUpdate (this); isUpdating = true;} // call the destroyItem of the Adapter to destroy the view mAdapter. destroyItem (this, ii. position, ii. object); needPopulate = true; if (mCurItem = ii. position) {// Keep the current item in the valid range newCurrItem = Math. max (0, Math. min (mCurItem, adapterCount-1); needPopulate = true;} continue;} if (ii. position! = NewPos) {if (ii. position = mCurItem) {// Our current item changed position. follow it. newCurrItem = newPos;} ii. position = newPos; needPopulate = true ;}} if (isUpdating) {mAdapter. finishUpdate (this);} Collections. sort (mItems, COMPARATOR); if (needPopulate) {// Reset our known page widths; populate will recompute them. final int childCount = getChildCount (); for (int I = 0; I <childCoun T; I ++) {final View child = getChildAt (I); final LayoutParams lp = (LayoutParams) child. getLayoutParams (); if (! Lp. isDecor) {lp. widthFactor = 0.f;}} setCurrentItemInternal (newCurrItem, false, true); requestLayout ();}}
PagerAdapter. POSITION_UNCHANGED, which determines whether the view is re-created. The default Apdapter code is as follows:
public int getItemPosition(Object object) { return POSITION_UNCHANGED; }
POSITION_UNCHANGED is returned by default. Therefore, if you do not overwrite the getItemPosition of the Adapter, the internal view effect cannot be changed. Next, we will transform the Code inherited from PagerAdapter and add the modification to getItemPosition, so that he can directly return POSITION_NONE. Every time the data changes, POSITION_NONE will cause the view to be rebuilt, which consumes more memory, avoid using this function when you do not need to change the internal view.
@Overridepublic int getItemPosition(Object object) {// TODO Auto-generated method stubreturn POSITION_NONE;}
Episode
If POSITION_NONE is returned, but there is no pager. removeAllViews (), the "first page" and "second page" do not disappear, and the "Third page" and "fourth page" also go up. They overlap with the first two pages, respectively.
If POSITION_UNCHANGED is returned, but pager. removeAllViews () is not returned, no changes are visible.