在一个 Android 应用中,我们可以使用 FragmentPageAdapter 来处理多 Fragment 页面的横向滑动。但是当 Fragment 对应的数据集发生改变时,我们都希望能够通过调用 mAdapter.notifyDataSetChanged() 来触发 Fragment 页面使用新的数据调整或重新生成其内容,可是当我们使用 notifyDataSetChanged() 后,我们会发现这个方法不会生效。那为什么会这样呢,之前遇到了相同的问题一直没法解决,在网上给出的乱七八糟的答案感觉也不是正解,终于在今早彻底解决了这个问题。我们先来了解下FragmentPagerAdapter的源代码。

    @Override  public Object instantiateItem(ViewGroup container, int position) {  if (mCurTransaction == null) {  mCurTransaction = mFragmentManager.beginTransaction();  }  final long itemId = getItemId(position);  // Do we already have this fragment?  String name = makeFragmentName(container.getId(), itemId);  Fragment fragment = mFragmentManager.findFragmentByTag(name);  if (fragment != null) {  if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);  mCurTransaction.attach(fragment);  } else {  fragment = getItem(position);  if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);  mCurTransaction.add(container.getId(), fragment,  makeFragmentName(container.getId(), itemId));  }  if (fragment != mCurrentPrimaryItem) {  fragment.setMenuVisibility(false);  fragment.setUserVisibleHint(false);  }  return fragment;  }  

我们特别关注下以下这句

    String name = makeFragmentName(container.getId(), itemId);  Fragment fragment = mFragmentManager.findFragmentByTag(name);  

根据原代码我们可以知道系统给每一个Fragment都打上了一个标签,通过标签来寻找相应的fragment,所以当我们第二次进入fragment的时候,fragment的oncreate,oncreateView方法都不会被调用的,因为FragmentPageAdapter 中的getitem()方法根本不会被调用,因为系统会根据标签找到相应的fragment,如果已经存在,就不会被调用,fragment有一个缓存机制在这里。那么如果我们一定要更新fragment,那么我们又该如何处理呢,我们就可以以其人之道,还治其人之身,我们可以通过tag标签找到我们相应的fragment,就可以对该fragment进行更新。那么我们现在就开始吧。

我们先来定义一个list<String> tagList 来存储一下tag

private List<String> tagList;

第二部 重写instantiateItem方法,把fragment对应的标签存储在taglist集合里

    public Object instantiateItem(ViewGroup container, int position) {  tagList.add(makeFragmentName(container.getId(), getItemId(position)));  return super.instantiateItem(container, position);  }  

makeFragmentName()是 FragmentPageAdapter源码里打fragment标签的方法

public static String makeFragmentName(int viewId, int index) {return "android:switcher:" + viewId + ":" + index;}

第三步我们再adapter里自己写一个update()方法

 public void update(int item) {Fragment fragment = fm.findFragmentByTag(tagList.get(item));if (fragment != null) {switch (item) {case 0:break;case 1:((QueryFragment) fragment).update();break;case 2:break;default:break;}}}

我们可以发现在queryFragment里也有一个update()方法,这个方法呢就是接下来我们用接口回掉机制更新我们相应fragment的要使用的方法,方法里的内容根据自己的需要编译就可以了。

好的现在万事具备只要实现fragment的数据更新问题就可以了,通过接口回掉机制来实现。

首先我们定义一个接口,让我们的主Activity来实现

    public interface FragmentListener {  public void onFragmentClickListener(int item);  }  

之后比如我们在A Fragment 里头插入了数据,需要BFragment对该数据进行显示,那么我们现在AFragment的onAttach方法中

    public void onAttach(Activity activity) {  super.onAttach(activity);  try {  listener = (FragmentListener)activity;  } catch (Exception e) {  e.printStackTrace();  }  }  

然后对数据更新的时候,我们就在Afragment调用这个接口

if (listener != null) {listener.onFragmentClickListener(1);}

然后我们回到Activity实现该接口里的方法,更新BFragment界面

public void onFragmentClickListener(int item) {adapter.update(item);adapter.update(item);}

大功告成了,贴一下完整的MainAcitivity代码吧!

package com.example.account.main;import java.util.ArrayList;import java.util.List;import com.example.account.add.AddFragment;
import com.example.account.query.QueryFragment;
import com.example.account.setting.SettingFragment;
import com.example.account.utils.PagerSlidingTabStrip;
import com.melhc.xiji.R;import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.KeyEvent;
import android.view.ViewGroup;
import android.widget.Toast;public class MainActivity extends FragmentActivity implements FragmentListener{private MyPagerAdapter adapter;private AddFragment addFragment;private List<String> tagList;private SettingFragment settingFragment;private boolean isExit;private QueryFragment queryFragment;private ViewPager pager;private PagerSlidingTabStrip tabs;private FragmentManager fm;private DisplayMetrics dm;private List<Fragment> list;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);pager = (ViewPager) findViewById(R.id.pager);tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);initFragment();fm = getSupportFragmentManager();tagList = new ArrayList<String>();adapter = new MyPagerAdapter(fm);pager.setAdapter(adapter);tabs.setViewPager(pager);}public void initFragment() {list = new ArrayList<Fragment>();addFragment = new AddFragment();queryFragment = new QueryFragment();settingFragment = new SettingFragment();list.add(addFragment);list.add(queryFragment);list.add(settingFragment);}public class MyPagerAdapter extends FragmentPagerAdapter {public MyPagerAdapter(FragmentManager fm) {super(fm);}private final String[] titles = { "1", "2", "3" };@Overridepublic CharSequence getPageTitle(int position) {return titles[position];}@Overridepublic int getCount() {return titles.length;}@Overridepublic Fragment getItem(int position) {return list.get(position);}public Object instantiateItem(ViewGroup container, int position) {tagList.add(makeFragmentName(container.getId(),(int) getItemId(position)));return super.instantiateItem(container, position);}public void update(int item) {Fragment fragment = fm.findFragmentByTag(tagList.get(item));if (fragment != null) {switch (item) {case 0:break;case 1:((QueryFragment) fragment).update();break;case 2:break;default:break;}}}}public static String makeFragmentName(int viewId, int index) {return "android:switcher:" + viewId + ":" + index;}public void onFragmentClickListener(int item) {adapter.update(item);adapter.update(item);}}

ViewPager+Fragment切换时无法更新数据问题解析(源代码分享)相关推荐

  1. android fragment实例化,Android使得Fragment 切换时不重新实例化

    以前实现Fragment的切换都是用replace方法实现 public void startFragmentAdd(Fragment fragment) { FragmentManager frag ...

  2. ViewPager -- Fragment 切换卡顿 性能优化

    当ViewPager切换到当前的Fragment时,Fragment会加载布局并显示内容,如果用户这时快速切换ViewPager,即 Fragment需要加载UI内容,而又频繁地切换Fragment, ...

  3. EasyNVR分屏切换时视频源丢失问题的优化分享

    EasyNVR视频平台能够进行多线程直播,新版更新的视频分屏功能也让多线程直播更加直观.经常有用户问我们最大能接入多少路视频流,其实这个是不固定的,具体还是要根据现场的网络和服务器来看.EasyNVR ...

  4. Android ViewPager Fragment 切换刷新数据,解决生命周期只走一次的问题

    前言 Activity的生命周期都应该熟悉,Fragment其标准生命周期也仅比Activity多出一些流程,如onCreateView(),比较好理解.了解Activity.Fragment的基础知 ...

  5. jquery+bootstrap实现tab切换, 每次切换时都请求数据, 点击提交分别向不同的地址提交数据...

    今天一个朋友叫帮做一个tab切换, 每一个tab内容区域都是从后台取出的数据, 这些数据要用表格的形式显示处理, 并且表格的内容区域可以修改, 如下所示: 例子查看请演示查看. 截图如图所示: 实现步 ...

  6. bootstrap tabale 点击_jquery+bootstrap实现tab切换, 每次切换时都请求数据, 点击提交分别向不同的地址提交数据...

    今天一个朋友叫帮做一个tab切换, 每一个tab内容区域都是从后台取出的数据, 这些数据要用表格的形式显示处理, 并且表格的内容区域可以修改, 如下所示: 例子查看请演示查看. 截图如图所示: 实现步 ...

  7. Android开发之ContentProvider结合LoaderManager加载数据(图文源代码分享)

    ContentProvider作为Android的四大存储方式之一,有着广泛的应用性,它暴露了数据地址,可以让其他应用访问数据,可以用于存储图片.通讯录等信息,这篇博文将详细介绍ContentProv ...

  8. Android开发之Service与Activity数据交互(源代码分享)

    Service想要与Activity进行数据交互,首先Activity先得绑定Service.bound service是service 的实现,它允许其他应用程序绑定到它并与之交互.要提供bound ...

  9. 影视php解析api,【3/3日更新】影视解析接口分享

    上一次分享几个月之前了,目前接口基本上改挂的都挂了 一般的稳定接口都是广告什么的,博主也分享一些安卓版的影视软件给大家,可以右上角搜索下. 全站无广告的,可以自己看 对你有帮助的话就帮忙推广下吧 更新 ...

最新文章

  1. java常用技术栈,HR的话扎心了
  2. Python中的排序sorted(d.items(), key=lambda x: x[1])
  3. PREV-3_蓝桥杯_带分数
  4. 大数据WEB阶段 shiro安全控制框架
  5. Microsoft MVC3 框架
  6. DataCapa 启动
  7. 平面直角坐标系中的旋转公式_【数理之路】初中范围推导三角函数倍角正弦公式...
  8. plsql学习笔记---plsql相关概念,以及基础结构
  9. 干货—MySQL常见的面试题+索引原理分析!
  10. layui数据表格如何获取id_LayUI之table数据表格获取行、行高亮等相关操作
  11. java中#{}和${}的区别
  12. 超越 Windows 时代!微软 Build 大会都透露了啥?
  13. JSP 实现登录注册功能
  14. 再来聊聊Redis到底是什么?
  15. 计算机网络与新媒体是什么,网络与新媒体专业课程是什么
  16. Allegro PCB Design GXL (legacy) 将brd文件另存为低版本文件
  17. 机器学习系列(三)——目标函数、损失函数以及代价函数
  18. h3c 模拟器 HCL 2.1.2 win10安装,vbox hyper-v vmware 兼容
  19. tool_AutoMan
  20. 马斯克:特斯拉正研发“世界上最好”的AI硬件

热门文章

  1. dsp处理浮点数_关于IQMATH和浮点数在DSP的深入理解
  2. hbuilderx 2.9.8 公用css样式_浅谈关于vue中scss公用的解决方案
  3. 1.QML语法、属性和元素
  4. 3D打印机分类与速度
  5. AWS 开源 SageMaker,帮助开发人员优化机器学习模型
  6. SharePoint Server 2007 Web内容管理中的几个关键概念
  7. 物联网帝国——孙正义职业生涯最大的豪赌
  8. FineUIMvc随笔(6)对比WebForms和MVC中表格的数据库分页
  9. delphi回调函数
  10. 一款基于jquery ui的动画提交表单