此处将为大家介绍关于FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别?的详细内容,并且为您解答有关viewpageradapter区别的相关问题,
此处将为大家介绍关于FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?的详细内容,并且为您解答有关viewpageradapter区别的相关问题,此外,我们还将为您介绍关于android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?、android – FragmentPagerAdapter instantiateItem使用Fragments?、android – FragmentPagerAdapter与ListFragment的getItem错误的有用信息。
本文目录一览:- FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?(viewpageradapter区别)
- android FragmentpagerAdapter和FragmentStatePagerAdapter的区别
- Android FragmentPagerAdapter在切换fragment时,怎么有些乱?
- android – FragmentPagerAdapter instantiateItem使用Fragments?
- android – FragmentPagerAdapter与ListFragment的getItem错误
FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?(viewpageradapter区别)
FragmentPagerAdapter
和 和有什么不一样FragmentStatePagerAdapter
?
关于FragmentPagerAdapter
谷歌的指南说:
这个版本的分页器最适合在需要分页的情况下使用少数通常更静态的片段,例如一组选项卡。用户访问的每个页面的片段都将保存在内存中,尽管它的视图层次结构在不可见时可能会被破坏。这可能会导致使用大量内存,因为片段实例可以保持任意数量的状态。对于较大的页面集,请考虑
FragmentStatePagerAdapter
.
关于FragmentStatePagerAdapter
:
当有大量页面时,此版本的寻呼机更有用,更像列表视图。当页面对用户不可见时,它们的整个片段可能会被销毁,只保留该片段的已保存状态。
FragmentPagerAdapter
与在页面之间切换时潜在的更多开销相比,这允许寻呼机保留与每个访问页面相关联的内存少得多
。
所以我只有3个片段。但它们都是具有大量数据的独立模块。
Fragment1
处理一些数据(用户输入)并通过活动将其传递给Fragment2
,这只是一个简单的ListFragment
.Fragment3
也是一个ListFragment
。
所以我的问题是 :我应该使用哪个适配器?FragmentPagerAdapter
还是FragmentStatePagerAdapter
?
答案1
小编典典就像文档说的那样,这样想。如果你要做一个像阅读器这样的应用程序,你不会希望一次将所有片段加载到内存中。您想Fragments
在用户阅读时加载和销毁。在这种情况下,您将使用FragmentStatePagerAdapter
.
如果您只显示 3
个不包含大量大量数据(如Bitmaps
)的“标签”,那么FragmentPagerAdapter
可能很适合您。另外,请记住,ViewPager
默认情况下会将
3
个片段加载到内存中。Adapter
您提到的第一个可能会破坏View
层次结构并在需要时重新加载它,第二个Adapter
仅保存状态Fragment
并完全破坏它,如果用户随后返回该页面,则检索状态。
android FragmentpagerAdapter和FragmentStatePagerAdapter的区别
1.FragmentPagerAdapterFragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。如文档所述,该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。FragmentPagerAdapter 重载实现了几个必须的函数,因此来自 PagerAdapter 的函数,我们只需要实现 getCount(),即可。且,由于 FragmentPagerAdapter.instantiateItem() 的实现中,调用了一个新增的虚函数 getItem(),因此,我们还至少需要实现一个 getItem()。因此,总体上来说,相对于继承自 PagerAdapter,更方便一些。
- getItem()
- 该类中新增的一个虚函数。函数的目的为生成新的 Fragment 对象。重载该函数时需要注意这一点。在需要时,该函数将被 instantiateItem() 所调用。
- 如果需要向 Fragment 对象传递相对静态的数据时,我们一般通过 Fragment.setArguments() 来进行,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。
- 如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么,这部分代码不适合放到 getItem() 中。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么很多人发现调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。
- instantiateItem()
- 函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。
- FragmentPagerAdapter 会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法。
- 如果需要在生成 Fragment 对象后,将数据集中的一些数据传递给该 Fragment,这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用 FragmentPagerAdapter.instantiateItem() 取得该函数返回 Fragment 对象,然后,我们该 Fragment 对象中对应的方法,将数据传递过去,然后返回该对象。
- 否则,如果将这部分传递数据的代码放到 getItem()中,在 PagerAdapter.notifyDataSetChanged() 后,这部分数据设置代码将不会被调用。
- destroyItem()
- 该函数被调用后,会对 Fragment 进行 FragmentTransaction.detach()。这里不是 remove(),只是 detach(),因此 Fragment 还在 FragmentManager 管理中,Fragment 所占用的资源不会被释放。
- 2.FragmentStatePagerAdapter
FragmentStatePagerAdapter 和前面的 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是,和 FragmentPagerAdapter 不一样的是,正如其类名中的 ''State'' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。
- getItem()
- 一个该类中新增的虚函数。
- 函数的目的为生成新的 Fragment 对象。
- Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。
- 由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。
- instantiateItem()
- 除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。
- FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。
- destroyItem()
- 将 Fragment 移除,即调用 FragmentTransaction.remove(),并释放其资源。
- getItem()
本文同步分享在 博客“xiangzhihong8”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
Android FragmentPagerAdapter在切换fragment时,怎么有些乱?
我用FragmentPagerAdapter 进行fragment切换,一共是5个fragment。
一开始的时候,是把前3个create了,我切换显示第2个的时候,程序把第4个第5个fragment进行了create;
切换显示第5个的时候,第2个fragment进行了onPause、onDestroyView等操作;第5个本身的onStart却没有被调用;
再切换显示第2个,第5个进行了onDestroyView等操作;第1个又进行了createView的操作;第2个自身的onStart也没有被调用;
=============================================================
我本来想在onStart和onPause里面,加一个变量,用于判断当前的fragment是不是正在显示,从而进行一些操作 ;这样一看,根本无法实现。
android – FragmentPagerAdapter instantiateItem使用Fragments?
@Override public Object instantiateItem(final ViewGroup container,final int position) { final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); int resId = 0; switch (position) { case 0: resId = R.layout.favorites_fragment; break; case 1: resId = R.layout.nearby_list_fragment; break; default: throw new IllegalArgumentException("Index cant be mapped to fragement:" + position); } final View view = inflater.inflate(resId,null); viewPager.addView(view,0); return view; }
因为我想使用片段我已经混淆了我的这个方法作为所有例子我可以找到膨胀视图而不是在那里创建片段.这该怎么做 ?
PS:我正在使用ActionBarSherlock lib 4.1 …
谢谢,
延
解决方法
android – FragmentPagerAdapter与ListFragment的getItem错误
它必须是简单的东西.
我正在展示大部分代码.错误在下一节中.
public class MainActivity extends FragmentActivity implements ActionBar.TabListener { public static final int TAB_COUNT = 3; public static InputMethodManager inputManager; SectionsPagerAdapter mSectionsPagerAdapter; ViewPager mViewPager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSectionsPagerAdapter = new SectionsPagerAdapter( getSupportFragmentManager()); // Set up the action bar. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mSectionsPagerAdapter); // When swiping between different sections,select the corresponding // tab. mViewPager .setonPagechangelistener(new ViewPager.SimpleOnPagechangelistener() { @Override public void onPageSelected(int position) { actionBar.setSelectednavigationItem(position); } }); // For each of the sections in the app,add a tab to the action bar. for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { actionBar.addTab(actionBar.newTab() .setText(mSectionsPagerAdapter.getPageTitle(i)) .setTabListener(this)); } // To control keyboard pop-up inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main,menu); return true; } @Override public void onTabUnselected(ActionBar.Tab tab,FragmentTransaction fragmentTransaction) { } @Override public void onTabSelected(ActionBar.Tab tab,FragmentTransaction fragmentTransaction) { // When the given tab is selected,switch to the corresponding page in // the ViewPager. mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabReselected(ActionBar.Tab tab,FragmentTransaction fragmentTransaction) { }
这是我的错误所在.
getItem的case 1,Type mismatch:无法从MainActivity.HistoryFragment转换为Fragment.它告诉我要么将方法返回类型更改为HistoryFragment,要么将newInstance()的返回类型更改为Fragment.哪里我也做不到.我见过的其他例子与我的代码几乎相同.我曾经尝试过,不经过论证.
public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { switch (i) { case 0: Fragment tipCalc = new TipCalcFragment(); return tipCalc; case 1: // Fragment history = new HistoryFragment(); return HistoryFragment.newInstance(i); //ERROR HERE case 2: Fragment stats = new StatsFragment(); return stats; } return null; }
我的HistoryFragment扩展了ListFragment.最后,它不会从String []值中提取,而是从数据库资源中提取.我只是想先设置一个结构,然后看看/播放布局.
public static class HistoryFragment extends ListFragment { // public HistoryFragment() { // } String[] values = new String[] { ... }; static HistoryFragment newInstance(int num) { HistoryFragment history = new HistoryFragment(); Bundle args = new Bundle(); args.putInt("num",num); history.setArguments(args); return history; } @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.history,container,false); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setlistadapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,android.R.id.text1,values)); } }
解决方法
我们今天的关于FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?和viewpageradapter区别的分享已经告一段落,感谢您的关注,如果您想了解更多关于android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?、android – FragmentPagerAdapter instantiateItem使用Fragments?、android – FragmentPagerAdapter与ListFragment的getItem错误的相关信息,请在本站查询。
本文标签: