Using the backstack and back buttons in viewpager

I use the viewpager to scroll between fragments and would like the back button to go to the previously viewed fragment, and not to end the action. Sorry if this is a duplicate of this question , however I did not find the answer very useful. Obviously, onBackPressed needs to be redefined, but I don’t know how to get and display the correct fragment. I assume I should use a fragmenter 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 to 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(); } } } 
+6
source share
5 answers

In the new design support library, I use this
I have the same problem and I am following this step.

In the main activity, where there are 3 fragments in the viewpager, I create a 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 onBackPressed in action,

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

Use this code in the class of the Fragment class. Remember to add return true;

 public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if ((keyCode == KeyEvent.KEYCODE_BACK)) { mViewPager.setCurrentItem(viewPageSelected - 1); return true; } return super.onKeyDown(keyCode, event); } 
+2
source

I had a similar problem, this is how I solved it. I think you can adapt the code to your problem if I understand what the problem is. I had a ViewPager with 6 fragments and I wanted to track page history and be able to use the back button to move back in history. I create a java.util.Stack<Integer> object, add fragment numbers to it (except when you use the back button, see below) and redefine onBackPressed() to force the last viewed fragment to pop up instead of using the back stack. when my story stack is not empty.

You want to avoid pushing items on the stack when you press the back button, otherwise you will get stuck between the two fragments if you continue to use the back button and not exit it.

My code is:

 MyAdapter mAdapter; ViewPager mPager; Stack<Integer> pageHistory; int currentPage; boolean saveToHistory; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = new MyAdapter(getSupportFragmentManager()); mPager = (ViewPager)findViewById(R.id.container); mPager.setAdapter(mAdapter); mPager.setOffscreenPageLimit(5); pageHistory = new Stack<Integer>(); mPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { if(saveToHistory) pageHistory.push(Integer.valueOf(currentPage)); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); saveToHistory = true; } @Override public void onBackPressed() { if(pageHistory.empty()) super.onBackPressed(); else { saveToHistory = false; mPager.setCurrentItem(pageHistory.pop().intValue()); saveToHistory = true; } }; 
+1
source

If you use the field to track the index of the previous page using mPager.getCurrentItem() after each user transition to a new fragment, then in the onBackPressed() method you should be able to call mPager.setCurrentItem(previousPage)

Or, if the user can only make pages in order, then you don’t need a field at all, and you could just do mPager.setCurrentItem(mPager.getCurrentItem()-1)

0
source

I created a custom ViewPager and implemented stack functions in it.

 public class CustomViewPager extends ViewPager { private Stack<Integer> stack = new Stack<>(); @Override public void setCurrentItem(int item, boolean smoothScroll) { stack.push(getCurrentItem()); super.setCurrentItem(item, smoothScroll); } public int popFromBackStack(boolean smoothScroll) { if (stack.size()>0) { super.setCurrentItem(stack.pop(), smoothScroll); return getCurrentItem(); } else return -1; } 
0
source

Source: https://habr.com/ru/post/952542/


All Articles