Viewpager+fragment数据更新问题解析
来源:互联网 发布:linux下timeout 编辑:程序博客网 时间:2024/05/06 13:43
在一个 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;
- @Override
- protected 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" };
- @Override
- public CharSequence getPageTitle(int position) {
- return titles[position];
- }
- @Override
- public int getCount() {
- return titles.length;
- }
- @Override
- public 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);
- }
- }
本文固定链接: http://www.devba.com/index.php/archives/5826.html | 开发吧
- Viewpager+fragment数据更新问题解析
- Viewpager+fragment数据更新问题解析
- Viewpager+fragment数据更新问题解析
- Viewpager+fragment数据更新问题
- Android-ViewPager+Fragment数据更新问题
- Viewpager+Fragment 数据更新
- ViewPager+Fragment切换时无法更新数据问题解析(源代码分享)
- Fragment与ViewPager之间更新数据相关问题
- ViewPager+Fragment布局中的Fragment数据更新
- FragmentActivity + ViewPager + Fragment + FragmentPagerAdapter 数据及时更新
- 【安卓笔记】ViewPager+Fragment布局中的Fragment数据更新
- Android 中 ViewPager+Fragment关于fragment的数据更新
- ViewPager 更新数据的问题
- Fragment+ViewPager网络请求数据问题
- Tablayout+viewpager+Fragment的数据加载问题
- Fragment嵌套ViewPager切换后数据消失ViewPager空白问题
- Fragment嵌套ViewPager切换后数据消失ViewPager空白问题
- Fragment嵌套ViewPager切换后数据消失ViewPager空白问题
- JAVA NIO学习笔记1 - 架构简介
- valueOf
- Java生成二维码
- 学习笔记:Deep Learning(四)循环神经网络
- JAVA
- Viewpager+fragment数据更新问题解析
- 计算机图形学(三)_图元的属性_16_ 反走样_5_过滤技术和像素移相
- 机器学习(六):K-Means聚类_Python
- [Log4j] 配置Log4j (写得太好了,忍不住把评论也转了,评论最后一条有大作用)
- windows系统下 python 安装过程
- 关键词提取综述
- 经测试能用springmvc的文件上传下载并解决ie8文件上传后提示下载
- Spring4深入理解01----Bean配置
- 网页简单的分帧技术