由于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 ViewPager实现多个图片水平滚动

    1.示意图                       2.实现分析 (1).xml配置 <!-- 配置container和pager的clipChildren=false, 并且指定margi ...

  2. @Html.Raw() 方法输出带有html标签的字符串

    @Html.Raw() 方法输出带有html标签的字符串,如:@Html.Raw("<div style='color:red'>输出字符串</div>") ...

  3. BZOJ3645: Maze(FFT多项式快速幂)

    Description 众维拉先后在中土大陆上创造了精灵.人类以及矮人,其中矮人是生性喜好常年居住在地下的洞穴的存在,他们挖掘矿物甚至宝石,甚至用他们的勤劳勇敢智慧在地底下创造出了辉煌宏大的宫殿,错综 ...

  4. XTUOJ 1238 Segment Tree

    Segment Tree Accepted : 3 Submit : 21Time Limit : 9000 MS Memory Limit : 65536 KB Problem Descriptio ...

  5. HDU——T 1075 What Are You Talking About

    http://acm.hdu.edu.cn/showproblem.php?pid=1075 Time Limit: 10000/5000 MS (Java/Others)    Memory Lim ...

  6. Hadoop-2.6.0上的C的API訪问HDFS

    在通过Hadoop-2.6.0的C的API訪问HDFS的时候,编译和执行出现了不少问题,花费了几天的时间,上网查了好多的资料,最终还是把问题给攻克了 參考文献:http://m.blog.csdn.n ...

  7. Vue绑定事件

    <!-- 方法处理器 --> <button v-on:click="doThis"></button> <!-- 内联语句 --> ...

  8. js关于循环的理解

    学习任何语言都离不开循环,js也是一样,看了网上的资料,整理一份关于js循环的理解. 1.最基础循环,js和其他高级语言一样使用for.while循环 (function() { for(var i= ...

  9. 7.cocos精灵创建和绘制

    创建Layer层的类 T2LayerSprite.h #pragma once #include "cocos2d.h" USING_NS_CC; class T2LayerSpr ...

  10. java中的九大隐藏变量.

          javax.servlet.jsp.JspWriter类型,代表输出流的对象.作用域为page(页面执行期) request:javax.servlet.ServletRequest的子类 ...