Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I don't think there is any kind of bug in the <code>PagerAdapter</code>. The problem is that understanding how it works is a little complex. Looking at the solutions explained here, there is a misunderstanding and therefore a poor usage of instantiated views from my point of view.</p> <p>The last few days I have been working with <code>PagerAdapter</code> and <code>ViewPager</code>, and I found the following:</p> <p>The <code>notifyDataSetChanged()</code> method on the <code>PagerAdapter</code> will only notify the <code>ViewPager</code> that the underlying pages have changed. For example, if you have created/deleted pages dynamically (adding or removing items from your list) the <code>ViewPager</code> should take care of that. In this case I think that the <code>ViewPager</code> determines if a new view should be deleted or instantiated using the <code>getItemPosition()</code> and <code>getCount()</code> methods.</p> <p>I think that <code>ViewPager</code>, after a <code>notifyDataSetChanged()</code> call takes it's child views and checks their position with the <code>getItemPosition()</code>. If for a child view this method returns <code>POSITION_NONE</code>, the <code>ViewPager</code> understands that the view has been deleted, calling the <code>destroyItem()</code>, and removing this view.</p> <p>In this way, overriding <code>getItemPosition()</code> to always return <code>POSITION_NONE</code> is completely wrong if you only want to update the content of the pages, because the previously created views will be destroyed and new ones will be created every time you call <code>notifyDatasetChanged()</code>. It may seem to be not so wrong just for a few <code>TextView</code>s, but when you have complex views, like ListViews populated from a database, this can be a real problem and a waste of resources.</p> <p>So there are several approaches to efficiently change the content of a view without having to remove and instantiate the view again. It depends on the problem you want to solve. <strong>My approach is to use the <code>setTag()</code> method for any instantiated view in the <code>instantiateItem()</code> method. So when you want to change the data or invalidate the view that you need, you can call the <code>findViewWithTag()</code> method on the <code>ViewPager</code> to retrieve the previously instantiated view and modify/use it as you want without having to delete/create a new view each time you want to update some value.</strong> </p> <p>Imagine for example that you have 100 pages with 100 <code>TextView</code>s and you only want to update one value periodically. With the approaches explained before, this means you are removing and instantiating 100 <code>TextView</code>s on each update. It does not make sense...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload