由于FragmentPagerAdapter内部存在缓存。因此调用notifyDataSetChanged()并不可以去更新Fragment的内容。

參考:http://www.devba.com/index.php/archives/5826.html

http://stackoverflow.com/questions/7263291/viewpager-pageradapter-not-updating-the-view/7287121#7287121

能够有两种解决的方法:

(1)重写Adapter的getItemPosition():

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

当调用notifyDataSetChanged()的时候。ViewPager会remove掉全部的view,然后又一次去载入。可行,可是效率低。

(2)在view上调用SetTag。然后用ViewPager.findViewWithTag()来找到要更新的view,然后做更新。

由于FragmentPagerAdapter内部缓存Fragment的时候,已经是依照tag的方式缓存的,因此。在更新的时候,我们仅仅要依据tag,拿到fragment,然后去更新fragment就能够了。

看下FragmentPagerAdapter的instantiateItem()方法:

public Object instantiateItem(ViewGroup container, int position)
{
if (this.mCurTransaction == null) {
this.mCurTransaction = this.mFragmentManager.beginTransaction();
} long itemId = getItemId(position); String name = makeFragmentName(container.getId(), itemId);//这里就是在生成fragment的tag
Fragment fragment = this.mFragmentManager.findFragmentByTag(name);//这里是依据tag查找
if (fragment != null)
{
this.mCurTransaction.attach(fragment);//找到直接attch
} else {
fragment = getItem(position);//找不到的时候。才会调用getItem this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
} if (fragment != this.mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
} return fragment;
}

依据原代码我们能够知道系统给每个Fragment都打上了一个标签,通过标签来寻找对应的fragment,所以当我们第二次进入fragment的时候。fragment的oncreate,oncreateView方法都不会被调用的。由于FragmentPageAdapter中的getitem()方法根本不会被调用,由于系统会依据标签找到对应的fragment。假设已经存在,就不会被调用,fragment有一个缓存机制在这里。

如今的问题是必需要做更新,那么能够这么弄:

public class FragmentViewPagerAdapter extends FragmentPagerAdapter {

	private FragmentManager mFragmentManager;
private List<String> mDatas;
private List<String> tagList = new ArrayList<String>(); public FragmentViewPagerAdapter(FragmentManager fm, List<String> datas) {
super(fm);
this.mFragmentManager = fm;
this.mDatas = datas;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
tagList.add(makeFragmentName(container.getId(), getItemId(position))); //把tag存起来
return super.instantiateItem(container, position);
} @Override
public void destroyItem(ViewGroup container, int position, Object object){
super.destroyItem(container, position, object);
tagList.remove(makeFragmentName(container.getId(), getItemId(position)));//把tag删掉
} @Override
public Fragment getItem(int position) {
String url = mDatas.get(position);
WebViewFragmentV4 webview = new WebViewFragmentV4(url);//本文測试的Fragment是一个WebViewFragment
		return webview;
} @Override
public int getCount() {
if (mDatas == null) {
return 0;
} else {
return mDatas.size();
}
} public void update(List<String> datas){
this.mDatas = datas;
notifyDataSetChanged();//并不能起到更新Fragment内容的作用。 } public void update(int position){//这个事真正的更新Fragment的内容
WebViewFragmentV4 fragment = (WebViewFragmentV4)mFragmentManager.findFragmentByTag(tagList.get(position));
if(fragment == null){
return;
}
fragment.update();
} private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
}

WebViewFragmentV4.java:

public class WebViewFragmentV4 extends Fragment {
private WebView mWebView;
private boolean mIsWebViewAvailable;
private String mUrl;
public WebViewFragmentV4(String url) {
this.mUrl = url;
} /**
* Called to instantiate the view. Creates and returns the WebView.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mWebView != null) {
mWebView.destroy();
}
mWebView = new WebView(getActivity());
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.loadUrl(mUrl);
mIsWebViewAvailable = true;
return mWebView;
} /**
* Called when the fragment is visible to the user and actively running.
* Resumes the WebView.
*/
@Override
public void onPause() {
super.onPause();
mWebView.onPause();
} /**
* Called when the fragment is no longer resumed. Pauses the WebView.
*/
@Override
public void onResume() {
mWebView.onResume();
super.onResume();
} /**
* Called when the WebView has been detached from the fragment. The WebView
* is no longer available after this time.
*/
@Override
public void onDestroyView() {
mIsWebViewAvailable = false;
super.onDestroyView();
} /**
* Called when the fragment is no longer in use. Destroys the internal state
* of the WebView.
*/
@Override
public void onDestroy() {
if (mWebView != null) {
mWebView.destroy();
mWebView = null;
}
super.onDestroy();
} public void update(){
if (mWebView != null) {
mWebView.reload();
}
} /**
* Gets the WebView.
*/
public WebView getWebView() {
return mIsWebViewAvailable ? mWebView : null;
} private static class MyWebViewClient extends WebViewClient { @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
} @Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
} @Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
} @Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
}

转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/47661443

測试代码:

//1. 初始化
viewpager = (ViewPager)this.findViewById(R.id.viewpager);
adapter = new FragmentViewPagerAdapter(getSupportFragmentManager(), null);
viewpager.setAdapter(adapter);
//2. 载入数据
List<String> urls = new ArrayList<String>();
urls.add("http://172.16.28.253:8080/web/1.jsp");
urls.add("http://172.16.28.253:8080/web/2.jsp");
urls.add("http://172.16.28.253:8080/web/3.jsp");
urls.add("http://172.16.28.253:8080/web/4.jsp");
adapter.update(urls);
//3. 做更新
Button update = (Button) this.findViewById(R.id.update);
update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(viewpager != null && adapter != null){
viewpager.setCurrentItem(3, true);
adapter.update(3);//又一次载入position是3的页面
}
}
});

重构一下:

(1)BaseFragmentPagerAdapter.java

public abstract class BaseFragmentPagerAdapter extends FragmentPagerAdapter{

	private FragmentManager mFragmentManager;
private List<String> tagList = new ArrayList<String>(); public BaseFragmentPagerAdapter(FragmentManager fm) {
super(fm);
this.mFragmentManager = fm;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
tagList.add(makeFragmentName(container.getId(), getItemId(position)));
return super.instantiateItem(container, position);
} @Override
public void destroyItem(ViewGroup container, int position, Object object){
super.destroyItem(container, position, object);
tagList.remove(makeFragmentName(container.getId(), getItemId(position)));
} private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
} public void update(int position){
Fragment fragment = (Fragment)mFragmentManager.findFragmentByTag(tagList.get(position));
if(fragment == null){
return;
}
if(fragment instanceof UpdateAble){//这里唯一的要求是Fragment要实现UpdateAble接口
((UpdateAble)fragment).update();
}
} public interface UpdateAble {
public void update();
}
}

以后我们的Adapter仅仅要继承BaseFragmentPagerAdapter就能够了。比方:

(2)FragmentViewPagerAdapter.java

public class FragmentViewPagerAdapter extends BaseFragmentPagerAdapter {

	private List<String> mDatas;

	public FragmentViewPagerAdapter(FragmentManager fm, List<String> datas) {
super(fm);
this.mDatas = datas;
} @Override
public Fragment getItem(int position) {
String url = mDatas.get(position);
WebViewFragmentV4 webview = new WebViewFragmentV4(url);
return webview;
} @Override
public int getCount() {
if (mDatas == null) {
return 0;
} else {
return mDatas.size();
}
} public void update(List<String> datas){
this.mDatas = datas;
notifyDataSetChanged();
}
}

跟普通的使用方法一样。唯一的要求是。Fragment必需要实现UpdateAble接口,perfect!

Android-ViewPager+Fragment数据更新问题的更多相关文章

  1. Android ViewPager Fragment使用懒加载提升性能

     Android ViewPager Fragment使用懒加载提升性能 Fragment在如今的Android开发中越来越普遍,但是当ViewPager结合Fragment时候,由于Androi ...

  2. Android - ViewPager+Fragment初始化问题

    Android应用开发中,经常会用到ViewPager + Fragment,虽然效果不错,但随之而来的还有一些问题,下面就说说其中的初始化问题. ViewPager初始化时会预加载前后的2个页面,即 ...

  3. android ViewPager+Fragment之懒加载

    说说写这篇博客的背景吧,前两天去面试,问到一个问题说的是:比如我们首页,是有3个fragment构成的,并且要是实现作用可以滑,那么这个最好的选择就是ViewPager+fragment了,但是我们知 ...

  4. Android ViewPager + Fragment的布局

    ViewPager And Fragment 1.之前有篇博客是讲ViewPager的用法的:http://www.cnblogs.com/liangstudyhome/p/3773156.html ...

  5. Android ViewPager+Fragment 在Activity中获取Fragment的控件

    如果ViewPager+Fragment实现Tab切换,在activity中利用adapter.getItem获取到fragment然后再根据fragment.的方法获取控件 //隐藏求租,以下代码用 ...

  6. Android ViewPager + Fragment实现滑动页面

    效果: PagerData类: package com.cloud.viewpagerdemo; import java.io.Serializable; class PagerData implem ...

  7. Android Viewpager+Fragment实现滑动标签页

    ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应. 主页布局 <?xml version="1.0" ...

  8. Android viewPager+fragment实现滑页效果

    先上图,手指在手机向左或者向右滑就可以实现相应的页面切换. 先看activity_main.xml文件,非常简单,主要是三个标题TextView和viewpager <?xml version= ...

  9. Android viewpager + fragment取消预加载

    1,在fragment中重写setUserVisibleHint方法private boolean isVisibleToUser;@Overridepublic void setUserVisibl ...

  10. android viewpager fragment 优化 切换界面 延时加载

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 使用 碎片的 设置用户可见暗示visible hint  这个方法来做到. hint 是 ...

随机推荐

  1. 【android】getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()的作用

    getCacheDir()方法用于获取/data/data/<application package>/cache目录 getFilesDir()方法用于获取/data/data/< ...

  2. CentOS下安装C/C++开发工具包的最佳方式

    如果你使用的是 Fedora, Red Hat, CentOS, 或者 Scientific Linux 系统,使用下面的命令安装GNU的C/C++开发包和编译器. # yum groupinstal ...

  3. Python(五) 包、模块、函数与变量作用域

    一.while循环与使用场景 CONDITION=1 while CONDITION <=5 : CONDITION +=1 print("hello") else: pri ...

  4. 在navicat中如何新建连接数据库

    前几天给大家分享了如何安装Navicat,没有来得及上车的小伙伴可以戳这篇文章:手把手教你安装Navicat——靠谱的Navicat安装教程.今天给大家分享一下Navicat的简单使用教程,具体的教程 ...

  5. SpringBoot 静态资源 加载位置

    1.配置自定义拦截器 /** * Copyright (C), 2017-2018, XXX有限公司 * FileName: WebConfig * Author: 丶Zh1Guo * Date: 2 ...

  6. Linux系统消息队列框架Kafka单机安装配置

    http://www.ithao123.cn/content-11128587.html

  7. cocos2dx 3.0正式版 在mac上新建项目

    触碰科技确定2.x版本号不会再更新了,会一直维护3.x的版本号.于是赶紧看看3.0的,简单浏览一下.类的使用方法和原来的几乎相同,仅仅是 表达的写法变了下,. . . . 以后肯定有非常多变化,速度熟 ...

  8. android Manifest.xml选项

    结构 继承关系 public final class Manifest extends Object java.lang.Object android.Manifest 内部类 class  Mani ...

  9. 黑马程序猿——JAVA面向对象的特性:封装,继承,多态

                                           - ----------android培训.java培训.java学习型技术博客.期待与您交流!------------  ...

  10. POJ2823 Sliding Window【双端队列】

    求连续的k个中最大最小值,k是滑动的,每次滑动一个 用双端队列维护可能的答案值 假设要求最小值,则维护一个单调递增的序列 对一開始的前k个,新增加的假设比队尾的小.则弹出队尾的,直到新增加的比队尾大. ...