标签:android viewpager fragment 缓存机制 源码
在一个 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);
我们先来定义一个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; } } }
好的现在万事具备只要实现fragment的数据更新问题就可以了,通过接口回掉机制来实现。
首先我们定义一个接口,让我们的主Activity来实现
public interface FragmentListener { public void onFragmentClickListener(int item); }
public void onAttach(Activity activity) { super.onAttach(activity); try { listener = (FragmentListener)activity; } catch (Exception e) { e.printStackTrace(); } }然后对数据更新的时候,我们就在Afragment调用这个接口
if (listener != null) { listener.onFragmentClickListener(1); }
public void onFragmentClickListener(int item) { adapter.update(item); adapter.update(item); }
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); } }
Viewpager+fragment数据更新问题解析,布布扣,bubuko.com
标签:android viewpager fragment 缓存机制 源码
原文地址:http://blog.csdn.net/gerogelin/article/details/38227977