Android -- process the notifyDataSetChanged value of ViewPager without refreshing
When Viewpager calls yydatasetchanged (), the interface is refreshed, which affects the implementation of our functions. You may choose to reset the adapter for Viewpager to refresh the page. However, this method is problematic in most cases. View method super. notifyDataSetChanged () calls PagerAdapter. policydatasetchanged ()/*** This method shocould be called by the application if the data backing this adapter has changed * and associated views shocould update. */public void policydatasetchanged () {mObservable. notifyChanged ();} indicates that this method should be called to refresh the data when the data appended to the adapter changes. This method calls a mObservable. notifyChanged (); we continue to follow up this method and enter the DataSetObservable class. We found the following code:/*** Invokes {@ link DataSetObserver # onChanged} on each observer. * Called when the contents of the data set have changed. the recipient * will obtain the new contents the next time it queries the data set. */public void policychanged () {synchronized (mObservers) {// since onChanged () is implemented by the app, it c Ocould do anything, including // removing itself from {@ link mObservers}-and that cocould cause problems if // an iterator is used on the ArrayList {@ link mObservers }. // to avoid such problems, just march thru the list in the reverse order. for (int I = mObservers. size ()-1; I> = 0; I --) {mObservers. get (I ). onChanged () ;}} is not the focus. Let's take a look at the type of this mObservers as an abstract class DataSetObserver. There are only two unimplemented methods in it. Who uses this? Abstract class, where Viewpager is found. After entering viewpager, we finally found the key method dataSetChanged for controlling data changes in viewpager. This method is as follows: void dataSetChanged () {// This method only gets called if our observer is attached, so mAdapter is non-null. boolean needPopulate = mItems. size () <mOffscreenPageLimit * 2 + 1 & mItems. size () <mAdapter. getCount (); int newCurrItem = mCurItem; boolean isUpdating = false; for (int I = 0; I <mItems. size (); I ++) {final ItemInfo ii = MItems. get (I); final int newPos = mAdapter. getItemPosition (ii. object); if (newPos = PagerAdapter. POSITION_UNCHANGED) {continue;} if (newPos = PagerAdapter. POSITION_NONE) {mItems. remove (I); I --; if (! IsUpdating) {mAdapter. startUpdate (this); isUpdating = true;} 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, mAdapter. getCount ()-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 <child Count; I ++) {final View child = getChildAt (I); final LayoutParams lp = (LayoutParams) child. getLayoutParams (); if (! Lp. isDecor) {lp. widthFactor = 0.f;}} setCurrentItemInternal (newCurrItem, false, true); requestLayout () ;}} focuses on this line of code: final int newPos = mAdapter. getItemPosition (ii. object); if (newPos = PagerAdapter. POSITION_UNCHANGED) {continue;} Called when the host view is attempting to determine if an item's position has changed. returns POSITION_UNCHANGED if the position of the given item has not Changed orPOSITION_NONE if the item is no longer present in the adapter. the default implementation assumes that items will never change position and always returnsPOSITION_UNCHANGED. it means that if the position of the item does not change, POSITION_UNCHANGED is returned. If POSITION_NONE is returned, the item at this position does not exist. The default implementation is to assume that the position of the item will never change, and the POSITION_UNCHANGED solution is returned. Therefore, we can try to modify the method of the adapter to overwrite the getItemPosition () method. When policydatasetchanged is called, the getItemPosition method returns POSITION_NONE manually to force viewpager to redraw all items. Class SearchAdapter extends PagerAdapter {private int mChildCount = 0; @ Override public void policydatasetchanged () {mChildCount = getCount (); super. policydatasetchanged () ;}@ Override public int getItemPosition (Object object) {if (mChildCount> 0) {mChildCount --; return POSITION_NONE;} return super. getItemPosition (object );}