保留viewpager片段android的状态

时间:2014-01-30 08:46:42

标签: android android-fragments android-viewpager

我在一个片段中有一个viewpager,我在其中显示3个片段,但是当我第一次打开片段时它打开正常,当我移动到另一个片段并返回到viewpager片段时,它没有显示片段查看寻呼机,然后我必须更改手机的方向或继续滑动viewpager以显示隐藏的片段。

我用google搜索它,现在我知道我必须将标记设置为每个片段并使用findfragmentbytag方法检索片段但问题是当我尝试将标记设置为片段时

getSupportFragmentManager().beginTransaction().add(myFragment, "Some Tag").commit();

上面的行崩溃我的应用程序和logcat显示“不能将标签设置为片段”,我知道我正在做一些愚蠢的错误

这是我片段的完整代码。如果能指导我在哪里编写用于设置片段标记的代码,我将非常感激。提前谢谢。

public class MatchesListingFragment extends Fragment implements ActionBar.TabListener {

    Context context;
    SectionsPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;
    ActionBar actionBar;
    Matchlistings db;
    Bundle savedInstanceState;

    Fragment livescore,fixture,results;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        this.savedInstanceState = savedInstanceState;
        db = new Matchlistings(getActivity());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_matches, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        context = getActivity().getApplicationContext();

        if(savedInstanceState == null){
            livescore = new LiveScoreListingFragment();
            fixture = new FixturesListingFragment();
            results = new ResultsListingFragment();
        }

        if(!Constants.is_listing_refreshed){
            Log.i(MainActivity.TAG,"refreshing list");
            db.loadListingsFromServer().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        actionBar = getActivity().getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        if(mSectionsPagerAdapter == null)
        mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
        mViewPager = (ViewPager) getView().findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });


        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            Tab tb = actionBar.newTab()
            .setText(mSectionsPagerAdapter.getPageTitle(i))
            .setTabListener(this);

            actionBar.addTab(tb);

        }
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        Fragment fragment;

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch(position){
            case 0:

                fragment = livescore;
                return fragment;
            case 1:
                fragment = fixture;
                return fragment;
            case 2:
                fragment = results;
                return fragment;
            case 3:
                fragment = new LiveScoreListingFragment();
                return fragment;
            }
            return null;
        }

        @Override
        public int getCount() {
            return 4;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
            case 0:
                return "LIVE";
            case 1:
                return "FIXTURES";
            case 2:
                return "RESULTS";
            case 3:
                return "HOT";
            }
            return null;
        }
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        actionBar.removeAllTabs();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    }

    @Override
    public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

}

enter image description here

编辑: 我现在试图通过标签从viewpager获取片段,而不是每次都创建新的片段。但问题仍然存在。

FixturesListingFragment fixture = (FixturesListingFragment) getActivity().getSupportFragmentManager().findFragmentByTag("android:switcher:"+R.id.pager+":1");
                if(fixture == null)
                    fixture = new FixturesListingFragment();

4 个答案:

答案 0 :(得分:10)

您是否尝试过使用setOffscreenPageLimit?如果您有3个页面,则将其设置为2.这样即使应用程序处于谜语状态,也不会重新创建页面。这是link

答案 1 :(得分:4)

我通过将FragmentPagerAdapter更改为FragmentStatePagerAdapter来修复此问题... 这是我在从link

下载的示例应用中看到的内容
/**
     * The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
     * three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter}
     * derivative, which will keep every loaded fragment in memory. If this becomes too memory
     * intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */

并改变它..但仍然想知道应该有一种方法来使用FragmentPagerAdapter

答案 2 :(得分:4)

我已经通过使用setOffScreenpageLimit(int)解决了我遇到的其他标签数量而解决了这个问题。

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new FragmentHome(), "Home");
    adapter.addFragment(new FragmentEProfile(), "e-Profile");
    adapter.addFragment(new FragmentResults(), "Results");
    adapter.addFragment(new FragmentOutpass(), "Outpass");
    viewPager.setAdapter(adapter);
    viewPager.setOffscreenPageLimit(3);
}

答案 3 :(得分:0)

尝试保留如下所述的实例:

 @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //add this line
    setRetainInstance(true);

    context = getActivity().getApplicationContext();