viewpager studio inside fragments example bar android android-fragments android-viewpager back-stack

android - studio - Uso de backstack y botón de retroceso en viewpager



on back pressed android fragment (5)

Estoy usando un visor para deslizar entre los fragmentos y me gustaría que el botón Atrás navegue al fragmento visto anteriormente en lugar de finalizar la actividad. Lo siento si esto es un duplicado de esta pregunta, pero no encontré la respuesta muy útil. Obviamente onBackPressed necesita ser anulado, pero no sé cómo obtener y mostrar el fragmento correcto. Supongo que debería usar backstack de fragmentmanager, pero getSupportFragmentManager().getBackStackEntryCount() siempre devuelve 0. ¿Tengo que agregar fragmentos manualmente a la backstack usando FragmentTransaction.addToBackStack() ? Si es así, ¿dónde debería agregar esto en mi adaptador?

Aquí está el código para mi actividad,

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(); } } }


He creado ViewPager personalizado e implementado la funcionalidad de pila en él.

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; }


Si utiliza un campo para realizar un seguimiento del índice de la página anterior utilizando mPager.getCurrentItem() después de cada vez que el usuario navega a un nuevo fragmento, en el método onBackPressed() , debe poder llamar a mPager.setCurrentItem(previousPage)

O bien, si el usuario solo puede hacer una página en orden, entonces no necesita un campo en absoluto, y podría simplemente hacer mPager.setCurrentItem(mPager.getCurrentItem()-1)


Tuve un problema similar, así es como lo resolví. Creo que puedes adaptar el código a tu problema si entendí cuál es tu problema. Tenía un ViewPager con 6 fragmentos y quería hacer un seguimiento del historial de la página y poder usar el botón Atrás para navegar hacia atrás en el historial. Creo un objeto java.util.Stack<Integer> , le agrego números de fragmento (excepto cuando utilizo el botón Atrás, vea abajo), y onBackPressed() para hacer que onBackPressed() el último fragmento visto en lugar de usar la pila de respaldo , cuando mi pila de historial no está vacía.

Desea evitar presionar elementos en la pila cuando presiona el botón Atrás, de lo contrario se quedará atrapado entre dos fragmentos si continúa utilizando el botón Atrás, en lugar de salir finalmente.

Mi código:

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; } };


Usa este código en la clase de Actividad de Fragmentos. No te olvides de agregar el retorno verdadero;

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); }


En la nueva biblioteca de soporte de diseño, uso esto
Tengo el mismo problema y sigo este paso

En la actividad principal donde hay 3 fragmentos en viewpager, creo pila y datos push y pop.

//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) { } }); }

y en la actividad onBackPressed in,

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