Android-ViewPager+Fragment数据更新问题
由于FragmentPagerAdapter内部存在缓存。因此调用notifyDataSetChanged()并不可以去更新Fragment的内容。
參考:http://www.devba.com/index.php/archives/5826.html
能够有两种解决的方法:
(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数据更新问题的更多相关文章
- Android ViewPager Fragment使用懒加载提升性能
Android ViewPager Fragment使用懒加载提升性能 Fragment在如今的Android开发中越来越普遍,但是当ViewPager结合Fragment时候,由于Androi ...
- Android - ViewPager+Fragment初始化问题
Android应用开发中,经常会用到ViewPager + Fragment,虽然效果不错,但随之而来的还有一些问题,下面就说说其中的初始化问题. ViewPager初始化时会预加载前后的2个页面,即 ...
- android ViewPager+Fragment之懒加载
说说写这篇博客的背景吧,前两天去面试,问到一个问题说的是:比如我们首页,是有3个fragment构成的,并且要是实现作用可以滑,那么这个最好的选择就是ViewPager+fragment了,但是我们知 ...
- Android ViewPager + Fragment的布局
ViewPager And Fragment 1.之前有篇博客是讲ViewPager的用法的:http://www.cnblogs.com/liangstudyhome/p/3773156.html ...
- Android ViewPager+Fragment 在Activity中获取Fragment的控件
如果ViewPager+Fragment实现Tab切换,在activity中利用adapter.getItem获取到fragment然后再根据fragment.的方法获取控件 //隐藏求租,以下代码用 ...
- Android ViewPager + Fragment实现滑动页面
效果: PagerData类: package com.cloud.viewpagerdemo; import java.io.Serializable; class PagerData implem ...
- Android Viewpager+Fragment实现滑动标签页
ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应. 主页布局 <?xml version="1.0" ...
- Android viewPager+fragment实现滑页效果
先上图,手指在手机向左或者向右滑就可以实现相应的页面切换. 先看activity_main.xml文件,非常简单,主要是三个标题TextView和viewpager <?xml version= ...
- Android viewpager + fragment取消预加载
1,在fragment中重写setUserVisibleHint方法private boolean isVisibleToUser;@Overridepublic void setUserVisibl ...
- android viewpager fragment 优化 切换界面 延时加载
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 使用 碎片的 设置用户可见暗示visible hint 这个方法来做到. hint 是 ...
随机推荐
- 【android】getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()的作用
getCacheDir()方法用于获取/data/data/<application package>/cache目录 getFilesDir()方法用于获取/data/data/< ...
- CentOS下安装C/C++开发工具包的最佳方式
如果你使用的是 Fedora, Red Hat, CentOS, 或者 Scientific Linux 系统,使用下面的命令安装GNU的C/C++开发包和编译器. # yum groupinstal ...
- Python(五) 包、模块、函数与变量作用域
一.while循环与使用场景 CONDITION=1 while CONDITION <=5 : CONDITION +=1 print("hello") else: pri ...
- 在navicat中如何新建连接数据库
前几天给大家分享了如何安装Navicat,没有来得及上车的小伙伴可以戳这篇文章:手把手教你安装Navicat——靠谱的Navicat安装教程.今天给大家分享一下Navicat的简单使用教程,具体的教程 ...
- SpringBoot 静态资源 加载位置
1.配置自定义拦截器 /** * Copyright (C), 2017-2018, XXX有限公司 * FileName: WebConfig * Author: 丶Zh1Guo * Date: 2 ...
- Linux系统消息队列框架Kafka单机安装配置
http://www.ithao123.cn/content-11128587.html
- cocos2dx 3.0正式版 在mac上新建项目
触碰科技确定2.x版本号不会再更新了,会一直维护3.x的版本号.于是赶紧看看3.0的,简单浏览一下.类的使用方法和原来的几乎相同,仅仅是 表达的写法变了下,. . . . 以后肯定有非常多变化,速度熟 ...
- android Manifest.xml选项
结构 继承关系 public final class Manifest extends Object java.lang.Object android.Manifest 内部类 class Mani ...
- 黑马程序猿——JAVA面向对象的特性:封装,继承,多态
- ----------android培训.java培训.java学习型技术博客.期待与您交流!------------ ...
- POJ2823 Sliding Window【双端队列】
求连续的k个中最大最小值,k是滑动的,每次滑动一个 用双端队列维护可能的答案值 假设要求最小值,则维护一个单调递增的序列 对一開始的前k个,新增加的假设比队尾的小.则弹出队尾的,直到新增加的比队尾大. ...