由于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. OOM框架AutoMapper基本使用(2)

    出于安全考虑,在后台与前台进行数据传输时,往往不会直接传输实体模型,而是使用Dto(Data transfer object 数据传输对象),这样在后台往前台传递数据时可以省略不必要的信息,只保留必要 ...

  2. 在performancepoint里面建立数据源的时候,总是发生以下的报警

    就是我在performancepoint里面建立数据源的时候,总是发生以下的报警.   在管理中心主页的“应用程序管理”部分,单击“管理服务应用程序”,然后单击“PerformancePoint Se ...

  3. Perl线程介绍

    Perl 中的线程 本文首先概述了线程的概念和意义,接着回顾了 Perl 语言中对线程支持的演化历史,然后通过一系列示例重点介绍了 Perl 中线程的实现,数据的共享以及线程间的同步,最后归纳并总结了 ...

  4. CentOS7/RedHat7的Apache配置介绍

    这里我们介绍yum安装httpd yum install -y httpd ************* [root@100 ~]# systemctl restart httpd [root@100 ...

  5. mysql的my.cnf文件详解

    一.缘由 最近要接手数据库的维护工作,公司首选MySQL.对于MySQL的理解,我认为很多性能优化工作.主从主主复制都是在调整参数,来适应不同时期不同数量级的数据. 故,理解透彻my.cnf里的参数是 ...

  6. 处理SpringMVC的时间错误:Field error in object 'sysDatumedetai' on field 'storagetime': rejected value [2017-11-27];

    错误: 十一月 27, 2017 8:26:11 下午 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service ...

  7. 利用HTTP代理录制Jmeter脚本

    1 測试计划中加入一个线程组1 2在"工作台"-非測试元件-加入"HTTP代理server" port: 代理server的port,默认8080,可自行改动, ...

  8. java架构解密——实时动态aop

    在上篇博客中个.咱们一起组建了一个容器,里面封装了业务,这样,咱们就将业务和服务的组装放到了client,而client就相当于咱们的开发中使用到的配置文件.大家发现问题了吗?就是我不能动态修改了?业 ...

  9. 与TCP/IP协议的初次见面(一)

    与TCP/IP协议的初次见面(一) 前言 今下午刚才女朋友那边回来,唉,算是情人节去找她吧,穷屌丝住不起好酒店,住的打折酒店,只是女朋友来姨妈了,万幸啊,牙还疼得不行,这几天光照应她了,没空写博客了. ...

  10. 具体解释Hibernate中的二级缓存

    1.前言 这篇博客再前几篇博客的基础上来解说一下.Hibernate中的二级缓存.二级缓存是属于SessionFactory级别的缓存机制. 第一级别的缓存是Session级别的缓存,是属于事务范围的 ...