ViewPager use record 2 -- Display Dynamic Data and viewpager Dynamic Data

Source: Internet
Author: User
Tags addall

ViewPager use record 2 -- Display Dynamic Data and viewpager Dynamic Data

ViewPager is a control in the v4 support library. I believe that almost all people who are familiar with Android development are familiar with it. I have to go over the old account here because I have used it for many requirements in my recent project, and I feel that I do not have a deep understanding of it. I plan to record the usage of ViewPager and some knowledge about it in the simplest use cases.

The code of this series will be stored in the Github repository. Each Article corresponds to a branch.

This is the first article about how ViewPager displays dynamic data and related knowledge points. There are several methods for ViewPager to Display Dynamic Data. The method getItemPosition of PagerAdapter cannot be used to aggregate the data together. The following describes the specific methods.

Error example

The previous article introduced how to display static data. The custom PagerAdapter in the Code has a setTexts method, whose content is as follows:

public synchronized void setTexts(List<String> texts) {      this.texts.clear();    if (texts != null && texts.size() > 0) {        this.texts.addAll(texts);    }    notifyDataSetChanged();}

The function is to clear the original data in the adapter list, copy the data passed in from the external to the List, and notify the adapter to update.

This method is called directly when external data is changed:

adapter.setTexts(randomData());  

It seems reasonable. After all, the adapters of components such as ListView are used in this way.

However, if you really run it, you will find that the data displayed by ViewPager is not updated as you wish. When there is a large amount of data, the previous data is not updated; when there is little data, you can slide to the left to see some of the old data when the page shows the last item; or even the case of a white screen.

For the code, see Github.

So how to update it correctly?

Use ViewPager. setAdapter to switch data sources

This is the simplest way to modify data and is suitable for use in scenarios where the entire data source changes.

Use the following code to initialize ViewPager:

adapter = new DynamicDataSetAdapter();  adapter.setTexts(randomData());viewPager = (ViewPager) findViewById(R.id.vp_viewpager_update);  viewPager.setAdapter(adapter);  

When we need to change the data displayed by ViewPager, we can:

// You can create a new PagerAdapter object or use an existing object // adapter = new DynamicDataSetAdapter (); adapter. setTexts (randomData (); viewPager. setAdapter (adapter );

For the code, see Github.

Why is it possible to use notifyDatasetChanged to update data correctly while setAdapter? This requires us to understand the update principle of ViewPager.

Update principle of ViewPager

View the source code of ViewPager and you will find that it has two member variables:

PagerAdapter mAdapter;  private PagerObserver mObserver;

PagerObserver is a private class defined within ViewPager, that is, it holds the reference of ViewPager by default, so you can call the ViewPager method.

private class PagerObserver extends DataSetObserver {      PagerObserver() {    }    @Override    public void onChanged() {        dataSetChanged();    }    @Override    public void onInvalidated() {        dataSetChanged();    }}

Actually, the name of PagerObserver indicates that it is an observer. PagerAdapter uses PagerObserver as the channel to notify ViewPager to call the dataSetChanged method to update data.

To view the source code of the dataSetChanged method, the key lies in:

...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;    }    ...}...

The dataSetChanged method calls the getItemPosition method of PagerAdapter. Once this method returns PagerAdapter. POSITION_UNCHANGED, the page will not be refreshed.

Because the default getItemPosition method is used, the implementation of the default getItemPosition method exactly returns this value:

public int getItemPosition(Object object) {      return POSITION_UNCHANGED;}

At this point, we can see why only calling yydatasetchanged after modifying the data will not refresh the page.

Next, let's take a look at the source code of the setAdapter method. The key lies in the first few lines of this method:

if (mAdapter != null) {      mAdapter.setViewPagerObserver(null);    mAdapter.startUpdate(this);    for (int i = 0; i < mItems.size(); i++) {        final ItemInfo ii = mItems.get(i);        mAdapter.destroyItem(this, ii.position, ii.object);    }    mAdapter.finishUpdate(this);    mItems.clear();    removeNonDecorViews();    mCurItem = 0;    scrollTo(0, 0);}...

Once the data adapter is not null, ViewPager destroys all data-related ItemInfo and calls the destroyItem method of the adapter to destroy the view one by one.

The code after setAdapter does not need to be viewed. Like the initialization process, the ItemInfo list and related data are generated.

This is why setAdapter can be called to update data.

Rewrite getItemPosition for more efficient data updates

Now that we know that getItemPosition determines the data update Rule, we only need to rewrite this method.

Of course, the most violent method is to directly let this method return POSITION_NONE. In effect, this is no different from using setAdapter, if PagerAdapter's notifyDatasetChanged is called, the original data will be destroyed and rebuilt.

A more secure approach is to work with the actual business data of the application to customize the method. The following is an example for reference only:

private static class DynamicDataSetAdapter extends PagerAdapter {      private List<String> texts;    public DynamicDataSetAdapter() {        texts = new ArrayList<>();    }    @Override    public int getCount() {        return texts.size();    }    @Override    public boolean isViewFromObject(View view, Object object) {        return object.equals(view);    }    @Override    public Object instantiateItem(ViewGroup container, int position) {        String text = texts.get(position);        TextView textView = new TextView(container.getContext());        textView.setTag(text);        textView.setText(text);        container.addView(textView);        return textView;    }    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        container.removeView((View) object);    }    @Override    public int getItemPosition(Object object) {        View view = (View) object;        String text = (String) view.getTag();        if (text == null) {            return PagerAdapter.POSITION_NONE;        }        int index = this.texts.indexOf(text);        if (index == -1) {            return PagerAdapter.POSITION_NONE;        }        return index;    }    public synchronized void setTexts(List<String> texts) {        this.texts.clear();        if (texts != null && texts.size() > 0) {            this.texts.addAll(texts);        }        notifyDataSetChanged();    }}

For the code, see Github.

This article is from the author's sync blog

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.