GVKun编程网logo

FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?(viewpageradapter区别)

41

此处将为大家介绍关于FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别?的详细内容,并且为您解答有关viewpageradapter区别的相关问题,

此处将为大家介绍关于FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?的详细内容,并且为您解答有关viewpageradapter区别的相关问题,此外,我们还将为您介绍关于android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?、android – FragmentPagerAdapter instantiateItem使用Fragments?、android – FragmentPagerAdapter与ListFragment的getItem错误的有用信息。

本文目录一览:

FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?(viewpageradapter区别)

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的区别

android FragmentpagerAdapter和FragmentStatePagerAdapter的区别

1.FragmentPagerAdapter
FragmentPagerAdapter 继承自 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(),并释放其资源。

本文同步分享在 博客“xiangzhihong8”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

Android FragmentPagerAdapter在切换fragment时,怎么有些乱?

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?

android – FragmentPagerAdapter instantiateItem使用Fragments?

我试图让我的FragmentPagerAdapter工作,但这些例子对于现实生活来说有点容易:

@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 …

谢谢,

解决方法

你究竟想做什么?显示班级的定义.您必须扩展FragmentPagerAdapter并实现公共抽象Fragment getItem(int position)以返回您的片段.不要覆盖instantiateItem()它已经在FragmentPagerAdapter中做了正确的事情.

android – FragmentPagerAdapter与ListFragment的getItem错误

android – FragmentPagerAdapter与ListFragment的getItem错误

我看了很多代码,无法解决这个问题. http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html

它必须是简单的东西.
我正在展示大部分代码.错误在下一节中.

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));
    }
}

解决方法

睡了之后我想通了.我导入android.app.ListFragment而不是android.support.v4.app.ListFragment

我们今天的关于FragmentPagerAdapter 和 FragmentStatePagerAdapter 有什么区别?viewpageradapter区别的分享已经告一段落,感谢您的关注,如果您想了解更多关于android FragmentpagerAdapter和FragmentStatePagerAdapter的区别、Android FragmentPagerAdapter在切换fragment时,怎么有些乱?、android – FragmentPagerAdapter instantiateItem使用Fragments?、android – FragmentPagerAdapter与ListFragment的getItem错误的相关信息,请在本站查询。

本文标签: