Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Contents of Viewpager lost on rotation

I have a project that has a MainActivity which hosts a fragment that hosts two other fragments via a Viewpager. It looks fine on first start up, but when I rotate, the two fragments in the Viewpager are lost. I've tried changing getFragmentManager to getChildFragmentManager but I would then get a Illegal state exception: Can't retain fragements that are nested in other fragments.

MainActivity.java:

import android.app.ActionBar;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;

public class MainActivity extends SlidingFragmentActivity {
@TargetApi(11)
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    getSupportFragmentManager()
    .beginTransaction()
    .replace(R.id.mainContentFrame, new WorkOutsContainerFrag())
    .commit();


     setBehindContentView(R.layout.menu);

     ActionBar actionBar = getActionBar();

        populate();

       SlidingMenu menu = getSlidingMenu();

        menu.setMode(SlidingMenu.LEFT);
        menu.setShadowWidthRes(R.dimen.shadow_width);
        menu.setShadowDrawable(R.drawable.shadow);
        menu.setBehindWidthRes(R.dimen.slidingmenu_offset);
        menu.setFadeDegree(0.35f);
        menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        menu.setSlidingEnabled(false);
        setSlidingActionBarEnabled(true);

        actionBar.setDisplayHomeAsUpEnabled(true);



    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            toggle();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private void populate() {

        ListView lv = (ListView) findViewById(R.id.listView1);
        String[] values = new String[] { "Workouts", "Information", "Ladders"};
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, android.R.id.text1, values);
        lv.setAdapter(adapter);


    }

}

WorkoutsContainerFrag.java:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.astuetz.PagerSlidingTabStrip;

public class WorkOutsContainerFrag extends Fragment {

private PagerSlidingTabStrip tabs;
private ViewPager pager;
private WorkoutsPagerAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.workoutscontainer, container, false);

    setRetainInstance(true);

    tabs = (PagerSlidingTabStrip) view.findViewById(R.id.workoutstabs);
    pager = (ViewPager) view.findViewById(R.id.workoutspager);
    adapter = new WorkoutsPagerAdapter(getFragmentManager());

    pager.setAdapter(adapter);

    final int pageMargin = (int)  TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources()
            .getDisplayMetrics());
    pager.setPageMargin(pageMargin);

    tabs.setViewPager(pager);

    return view;

}

private GymWorkoutsFragment gymWorkoutsFragment;
private OCWorkoutsFragment ocWorkoutsFragment;

public class WorkoutsPagerAdapter extends FragmentPagerAdapter {

    private final String[] TITLES = {"Gym Workouts", "OC Workouts"};

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


    @Override
    public CharSequence getPageTitle(int position) {
        return TITLES[position];
    }

    @Override
    public int getCount() {
        return TITLES.length;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            gymWorkoutsFragment = new GymWorkoutsFragment();
            return (Fragment)gymWorkoutsFragment;

        case 1:
            ocWorkoutsFragment = new OCWorkoutsFragment();
            return (Fragment)ocWorkoutsFragment;

    }
        return null;
}

} }

like image 836
Racepace Avatar asked Dec 19 '13 18:12

Racepace


People also ask

What is the difference between ViewPager and ViewPager 2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

How do I refresh ViewPager fragments?

OnPageChangeListener is the correct way to go, but you will need to refactor your adapter a bit in order to keep a reference to each Fragment contained in the FragmentPagerAdapter. Then, instead of creating a new Fragment, use the one contained in the adapter: mViewPager. addOnPageChangeListener(new ViewPager.

Can I use ViewPager with views not with fragments?

yes...you can use View instead of Fragment in viewpager. Here you can Find Whole example that will help you to achieve Viewpager without Fragment. Go through this documentation. Save this answer.

Is ViewPager deprecated?

This method may be called by the ViewPager to obtain a title string to describe the specified page. This method is deprecated.


2 Answers

Probably, if u wish to retain the fragment instance, you can try using this,

ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setOffscreenPageLimit(2); // No of fragments to be preserved

Cheers!!

like image 24
siva Avatar answered Sep 24 '22 02:09

siva


The answer is actually super simple, it was to replace FragmentPagerAdapter with FragmentStatePagerAdapter

like image 63
Racepace Avatar answered Sep 23 '22 02:09

Racepace