博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Viewpager+fragment数据更新问题解析
阅读量:6900 次
发布时间:2019-06-27

本文共 6825 字,大约阅读时间需要 22 分钟。

在一个 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
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
tagList; private SettingFragment settingFragment; private boolean isExit; private QueryFragment queryFragment; private ViewPager pager; private PagerSlidingTabStrip tabs; private FragmentManager fm; private DisplayMetrics dm; private List
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
(); adapter = new MyPagerAdapter(fm); pager.setAdapter(adapter); tabs.setViewPager(pager); } public void initFragment() { list = new ArrayList
(); 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); } }

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/zhangqingquan/p/4099321.html

你可能感兴趣的文章
Hadoop2.6+Zookeeper3.4+Hbase1.0部署安装
查看>>
测试唯一ID支持多大的并发量
查看>>
centos 安装部署docker与局域网主机相通详细配置
查看>>
老鸟经验谈linux运维人员到底要不要考linux认证
查看>>
solr配置
查看>>
CSS HACK 区别于ie6/7/8/firefox的小问题
查看>>
编译一个可以用Qemu进行Debug的Linux Kernel:
查看>>
linux 服务器 keras 深度学习环境搭建
查看>>
xshell+xmanager远程linux图形化界面
查看>>
布局模型
查看>>
我的友情链接
查看>>
jquery 实现复选框 全选/反选
查看>>
我的友情链接
查看>>
http://www.mossle.com/wiki/13.lemon-devguide/0008.modeler
查看>>
UI自动化测试之selenium(3)——采坑填坑集
查看>>
全美五大最创新的公司
查看>>
传微软将于明年推出Linux版Office
查看>>
后LHC时代对撞机:瞬间输出能量超全球电力千倍
查看>>
Leetcode#75Sort Colorsetcode
查看>>
3月30日作业
查看>>