0

当我实例化三个不同的(n、n+1、n+2)片段时,我有一个 FragmentActivity。我需要在用户滑动到每个 Fragment 时保持更新,所以我在 Fragment Activity 中使用了ViewPager.SimpleOnPageChangeListener.onPageSelected,所以当用户滑动到 n+1 或 n+2 Fragment 并再次滑动到 n 时,该函数会更新内容。如果我在片段 n+1 中,不使用此解决方法,则 n 和 n+2 都已加载!相反,我希望在用户滑动到片段时加载片段,而不需要“预加载”。

这种解决方法对我来说很好,但它有一个问题:应用程序启动时列表中的第一个 n Fragment 不会加载其内容。要加载它的内容,我必须滑动到 n+1 然后返回到 n。

我知道片段的内容应该设置在实例化片段时调用的类上,并且扩展片段类,但是这样我不知道如何跟上每个片段的最新状态,就像我使用onPageSelected

有什么建议么?

编辑 1: 我在onCreate()中以这种方式证明了我的片段:

    for(int x = 0; x < 3; x++) {
        Bundle b = new Bundle();
        b.putString( "id" , x );
        Fragment myFrag = Fragment.instantiate( myContext , Mm_FragmentPage.class.getName() );
        myFrag.setArguments( b );
        fragments.add(myFrag);
    }

然后我在ViewPager中设置适配器:

    mPagerAdapter = new PagerAdapter( super.getSupportFragmentManager() , fragments );
    mPager.setAdapter( mPagerAdapter );

然后我在TitlePageIndicator中使用适配器

    titleIndicator = (TitlePageIndicator) findViewById( R.id.titleFragments );
    titleIndicator.setViewPager( mPager );
    titleIndicator.setOnPageChangeListener( new myPageChangeListener() );

最后,PagerAdapter类:

public class PagerAdapter extends FragmentPagerAdapter
{
    // fragments to instantiate in the viewpager
    private List<Fragment> fragments;

    // constructor
    public PagerAdapter(FragmentManager fm, List<Fragment> fragments)
    {
        super(fm);
        this.fragments = fragments;
    }

    // return access to fragment from position, required override
    @Override
    public Fragment getItem(int position)
    {
        return this.fragments.get(position);
    }

    // number of fragments in list, required override
    @Override
    public int getCount()
    {
        return this.fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position)
    {
        return getResources().getStringArray( R.array.tab_header_name )[ position ];
    }
}
4

1 回答 1

0

好的,所以首先你需要在 ViewPager 上设置OnPageChangeListener并实现方法onPageSelected(int i)并调用适配器的notifyDataSetChanged(),如下所示:

    mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i2) {

        }

        @Override
        public void onPageSelected(int i) {
            //Tell the adapter that the content was changed
            mPager.getAdapter().notifyDataSetChanged();

        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    });

为了保持片段更新,您需要扩展FragmentStatePagerAdapter而不是像您所做的那样扩展FragmentPagerAdapter 。不同之处在于,使用FragmentPagerAdapter时,ViewPager永远不会重新创建片段,而在FragmentStatePagerAdapter中它会。

然后在getItem(..)上,确保通过setArguments()将内容传递给其参数,从而返回带有新内容的片段的新实例。然后重写getItemPosition(..)以告诉适配器找不到片段,因此它必须重新创建它。

public class MyPagerAdapter extends FragmentStatePagerAdapter {
        //List to hold the fragments to be shown
        //NOTE: It's a list of Fragment classes, not a list of Fragment instances!
        private List<Class<? extends Fragment> fragments;

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
            fragments.add(SomeFragment.class); 
            fragments.add(AnotherFragment.class);
            fragments.add(MoreFragment.class);
        }

        @Override
        public Fragment getItem(int i) {
            try {
                //Creates a new instance of the fragment
                Fragment instance = fragments.get(i).newInstance();
                //Put the new content by passing Bundle with new content
                instance.setArguments(args);
                return instance;
                } catch (InstantiationException e) {
                  e.printStackTrace();
                } catch (IllegalAccessException e) {
                  e.printStackTrace();
              }
            return null;
          }


        @Override
        public int getItemPosition(Object object) {
            //NOTE: you might want to put better logic here
            return POSITION_NONE;
        }

        @Override
        public int getCount() {
            return pages.size();
        }
    }

每次从一个片段滑动到另一个片段时,onPageSelected()将被调用 notifyDataSetChanged() 触发,这将强制适配器检查片段的位置是否已更改。由于我们在getItemPosition(..)中返回 POSITION_NONE ,因此适配器认为位置已更改,然后将调用getItem(i)。在getItem(i)中,我们返回一个新实例(可选地,传递新参数)。问题解决了!:)

我刚刚自己测试了它,创建了一个小应用程序,它有一个计数器,每次用户滑动页面时它都会增加并且它可以工作!

这样您就可以删除ViewPager.SimpleOnPageChangeListener.onPageSelected了解有关 ViewPager 的更多信息。

于 2013-09-02T22:17:46.127 回答