Using backstack and back button in viewpager

Igd picture Igd · Aug 26, 2013 · Viewed 13.5k times · Source

I'm using a viewpager to swipe between fragments and would like the back button to navigate to the previously viewed fragment rather than ending the activity. Sorry if this is a duplicate of this question however I didn't find the answer very helpful. Obviously onBackPressed needs to be overridden, but I don't know how to get and display the correct fragment. I assume that I should use the fragmentmanager's backstack, but getSupportFragmentManager().getBackStackEntryCount() always returns 0. Do I need to manually add fragments to the backstack using FragmentTransaction.addToBackStack()? If so, where would I add this in my adapter?

Here is the code for my activity,

public class PagerActivity extends FragmentActivity {

ArrayList<Sale> sales;
MyAdapter mAdapter;
ViewPager mPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent it = getIntent();
    this.sales = (ArrayList<Sale>) it.getExtras().get("sales");
    int position = it.getExtras().getInt("position");

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);

    setContentView(R.layout.fragment_pager);
    mAdapter = new MyAdapter(getSupportFragmentManager());
    mPager = (ViewPager) findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);
    mPager.setCurrentItem(position);

}

public class MyAdapter extends FragmentPagerAdapter {
    public MyAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

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

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        super.destroyItem(container, position, object);
    }

    @Override
    public Fragment getItem(int position) {
        SalesThumbFragment frag = new SalesThumbFragment();
        return frag.newInstance(sales.get(position));
    }
}

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.sales_controller, menu);
    return true;
}

@Override
public void onBackPressed() {
  if(getSupportFragmentManager().getBackStackEntryCount() != 0) {
    getSupportFragmentManager().popBackStack();
  } else {

    super.onBackPressed();
  }
}


}

Answer

Ravikant Paudel picture Ravikant Paudel · Oct 9, 2015

In new design support library, i use this
I have same issue and i follow this step

In the main activity where there are 3 fragment in viewpager i create stack and push and pop data.

//private Stack<Integer> stackkk;  ==> As i get edit suggestion 
private Stack<Integer> stackkk = new Stack<>(); // Edited 
private ViewPager mPager;
private int tabPosition = 0;



    mTabLayout.setupWithViewPager(mPager);
    mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
    mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            tabPosition = tab.getPosition();
            mPager.setCurrentItem(tab.getPosition());

            if (stackkk.empty())
                stackkk.push(0);

            if (stackkk.contains(tabPosition)) {
                stackkk.remove(stackkk.indexOf(tabPosition));
                stackkk.push(tabPosition);
            } else {
                stackkk.push(tabPosition);
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            tabPositionUnselected = tab.getPosition();
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {
        }
    });
}

and in the onBackPressed in activity,

@Override
public void onBackPressed() {
    if (stackkk.size() > 1) {
        stackkk.pop();
        mPager.setCurrentItem(stackkk.lastElement());
    } else {
    }
}