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(ViewGroupcontainer, 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()





更多相关文章

  1. Android(安卓)应用更新使用Bugly
  2. Android(安卓)Fragment 体系源码跟踪笔记(1)
  3. android 中自动更新时间机制
  4. Android(安卓)Studio 更新0.6.1出现的问题
  5. (持续更新, 目前含100+工具类) DevUtils 是一个 Android(安卓)工
  6. 关于 android Intent 传对象和对象数组的一些操作
  7. 编译源码生成的SDK,创建android project 没有proguard.cfg问题
  8. Android通过HttpURLConnection获取JSON并进行UI更新
  9. Android实现文件的复制

随机推荐

  1. android上特效(源代码)
  2. 获取sd卡容量
  3. Unity Android(安卓)崩溃 处理
  4. ”Android(安卓)Application Framework F
  5. Android(安卓)监听手机锁屏
  6. GPS定位那点事
  7. Notification 最简单的使用
  8. 如何创建一个baseactivity
  9. 12 Android(安卓)AsyncHttpClient 的简单
  10. android WebView使用示例