Pila trasera personalizada para cada fragmento en TabHost en Android
Ya que el TabActivity es obsoleto traté de reemplazarlo con Fragmentos que ya se ha mencionado en el sitio web de desarrolladores android. Pero como ustedes ya saben, hubo un problema acerca de reemplazar las pestañas con fragmentos, ya que solo habrá una actividad, que es Fragment Activity, no hay pila trasera para cada uno de los fragmentos y como se puede ver en las otras preguntas SO más De los desarrolladores estaban diciendo que usted necesita para administrar su propia pila trasera personalizada como una solución.
He creado e implementado mi propia pila trasera personalizada como se puede ver a continuación, funciona perfecto Puedo rastrear cada fragmento en cada ficha.
- ¿Por qué mi 'actionBarTabStyle' personalizado no anula el estilo / tema predeterminado?
- Buscar usuarios en el host de pestañas android
- Inflar un diseño con ImageButton en Fragmento mediante programación
- Establecer la intención de volver clave en TabActivity
- Las pestañas TabHost de Android roban el enfoque al utilizar el teclado de hardware
Tab1
Fragment1 > Fragment2 > Fragment3
Tab2
Fragment5 > Fragment6
De acuerdo con la navegación anterior, si navego de Fragmento1 a Fragmento 3 y Después de eso Si cambio la pestaña a Tab2 y vuelvo a Tab1, todavía puedo ver el Fragmento3 e incluso puedo navegar de nuevo a Fragmento1 con mi pila trasera personalizada.
Pero el problema es, Cuando vuelvo a Tab1 y ver el Fragmento3, el Fragmento3 se vuelve a crear y no puedo ver los cambios que dejé atrás antes de cambiar la pestaña a Tab2.
Aquí está mi pila posterior de encargo;
public static HashMap<String, Stack<Fragment>> customBackStack; public static Stack<Fragment> simpleStack; public static Stack<Fragment> contactStack; public static Stack<Fragment> customStack; public static Stack<Fragment> throttleStack; public static Stack<Fragment> homeStack; customBackStack = new HashMap<String, Stack<Fragment>>(); homeStack = new Stack<Fragment>(); simpleStack = new Stack<Fragment>(); contactStack = new Stack<Fragment>(); customStack = new Stack<Fragment>(); throttleStack = new Stack<Fragment>(); customBackStack.put("home", homeStack); customBackStack.put("simple", simpleStack); customBackStack.put("contacts", contactStack); customBackStack.put("custom", customStack); customBackStack.put("throttle", throttleStack);
Y aquí está onTabChanged método;
public void onTabChanged(String tabId) { TabInfo newTab = mTabs.get(tabId); if (mLastTab != newTab) { FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); if (mLastTab != null) { if (mLastTab.fragment != null) { ft.detach(mLastTab.fragment); } } if (newTab != null) { if (newTab.fragment == null) { if (!customBackStack.get(tabId).isEmpty()) { Fragment fragment = customBackStack.get(tabId).pop(); customBackStack.get(tabId).push(fragment); ft.replace(mContainerId, fragment); } } else { if (!customBackStack.get(tabId).isEmpty()) { Fragment fragment = customBackStack.get(tabId).pop(); customBackStack.get(tabId).push(fragment); ft.replace(mContainerId, fragment); } } } mLastTab = newTab; ft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } }
Y aquí está enBackPressed;
public void onBackPressed() { Stack<Fragment> stack = customBackStack.get(mTabHost.getCurrentTabTag()); if (stack.isEmpty()) { super.onBackPressed(); } else { Fragment fragment = stack.pop(); if (fragment.isVisible()) { if (stack.isEmpty()) { super.onBackPressed(); } else { Fragment frg = stack.pop(); customBackStack.get(mTabHost.getCurrentTabTag()).push(frg); transaction = getSupportFragmentManager().beginTransaction(); transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right, R.anim.slide_in_right, R.anim.slide_out_left); transaction.replace(R.id.realtabcontent, frg).commit(); } } else { getSupportFragmentManager().beginTransaction().replace(R.id.realtabcontent, fragment).commit(); } } }
Como resultado, la pila trasera personalizada funciona bien, excepto el último fragmento antes de cambiar la ficha se vuelve a crear después de volver a la pestaña, no se reanuda como en la actividad de la pestaña.
¿Alguna idea de cómo resolverlo?
EDITAR
Puede encontrar mi aplicación de ejemplo aquí como una solución con respecto a este problema.
GitHub
- OnClickListener en pestañas no funciona
- Android - onTabChanged no se invoca al seleccionar una pestaña diferente
- ¿Cómo implementar la actividad tabulada doble en android?
- Cambiando dinámicamente los fragmentos dentro de un host de fichas de fragmentos?
- Buscando un estilo TabHost universal que funcione en Android, HTC Sense, Samsung, etc. skins
- Android elimina el espacio entre las pestañas de tabwidget
- Problema con el diseño de interfaz de usuario TabHost
- La actividad en el host de tabulación se queda en blanco
He modificado la lista de muestra de googles a la siguiente:
public static class TabListener<T extends SherlockFragment> implements ActionBar.TabListener { private final SherlockFragmentActivity mActivity; private final String mTag; private final Class<T> mClass; private final Bundle mArgs; public SherlockFragment mFragment; private final Stack<SherlockFragment> mStack; public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) { this(activity, tag, clz, null, null); } public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz, Bundle args, Stack<SherlockFragment> stack) { mActivity = activity; mTag = tag; mClass = clz; mArgs = args; mStack = stack; // Check to see if we already have a fragment for this tab, probably // from a previously saved state. If so, deactivate it, because our // initial state is that a tab isn't shown. mFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.detach(mFragment); ft.commit(); } } public void onTabSelected(Tab tab, FragmentTransaction ft) { // we need to reattach ALL fragments thats in the custom stack, if we don't we'll have problems with setCustomAnimation for fragments. if (mFragment == null) { mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName(), mArgs); ft.replace(android.R.id.content, mFragment, mTag); } else { ft.attach(mFragment); } if(mStack != null) { for(SherlockFragment fragment: mStack) { ft.attach(fragment); } } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { ft.detach(mFragment); } if(mStack != null) { for(SherlockFragment fragment: mStack) { if(fragment!= null && !fragment.isDetached()) { ft.detach(fragment); } } } } public void onTabReselected(Tab tab, FragmentTransaction ft) { } }
Y la actividad onKeyDown methode I pasa a siguiente:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { int index = getSupportActionBar().getSelectedNavigationIndex(); Stack<SherlockFragment> stack = null; SherlockFragment fragment = null; String rootTag = null; switch(index) { case 0: stack = mWatersTabListener.mStack; fragment = mWatersTabListener.mFragment; rootTag = mWatersTabListener.mTag; break; case 1: stack = mHarborTabListener.mStack; fragment = mHarborTabListener.mFragment; rootTag = mHarborTabListener.mTag; break; } if(stack.isEmpty()) { return super.onKeyDown(keyCode, event); } else { SherlockFragment topFragment = stack.pop(); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.setCustomAnimations(R.anim.fragment_slide_right_enter, R.anim.fragment_slide_right_exit); if(topFragment != null && !topFragment.isDetached()) { ft.detach(topFragment); } if(stack.isEmpty()) { ft.replace(android.R.id.content, fragment, rootTag); ft.commit(); return true; } else { SherlockFragment nextFragment = stack.peek(); ft.replace(android.R.id.content, nextFragment); ft.commit(); return true; } } } return super.onKeyDown(keyCode, event); }
Las cosas importantes a tener en cuenta es que usted tiene que adjuntar todos los fragmentos en su pila personalizada cuando se selecciona y tiene que separar todo así cuando no seleccionada. Si hay un problema con la comprensión de los fragmentos de código sólo tiene que preguntar.
- El montón de memoria de aplicaciones de Android sigue creciendo
- Android :: DRM para contenido de video