使用ViewPager時,如何對view進行更新

來源:互聯網
上載者:User

ViewPager是個好東西,但往往有些業務需要是android無法滿足的,比如要更新ViewPager的特定view

本帖其實就是StackOverflow的總結帖

原帖見http://stackoverflow.com/questions/7263291/viewpager-pageradapter-not-updating-the-view

一種簡單快速的辦法:

Override getItemPosition in your PagerAdapter like this:public int getItemPosition(Object object) {    return POSITION_NONE;}This way, when you call notifyDataSetChanged(), the view pager will be updated.

這種方法其實就是將制定位置的item給destroy掉,然後重新建立一個新的,很暴力。某大牛寫到

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

Good! 是個很好的思路,對PagerAdapter的行為做手腳,來實現我們想要的效果。

文中提到在 instantiateItem(ViewGroup container,
int position) 時,進行setTag(),然後在需要更新的view的地方,使用findViewWithTag (Object tag)擷取到要操作的view,直接操作這個view即可。


但是PagerAdapter的instantiateItem方法寫到

Create the page for the given position. The adapter is responsible for adding the view to the container given here, although it only must ensure this is done by the time it returns from finishUpdate(ViewGroup).

所以覆蓋instantiateItem是不保險的,因為這時候view可能並未被建立,而在finishUpdate()時是確保view可用的。

大致的順序

1.PagerAdapter.instantiateItem()

2.FragmentPagerAdapter.getItem()  -- 這時並沒有建立fragment的view

3.FragmentManager.moveToState() -- 這裡調用了fragment的onCreateView()

4.PagerAdapter.finishUpdate()


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.