Manejo del título de ActionBar con la pila trasera del fragmento?

Tengo una Activity en la que carga en un ListFragment y, al hacer clic, perfora un nivel y se muestra un nuevo tipo de ListFragment , reemplazando el original (utilizando el método showFragment continuación). Esto se coloca en la pila trasera.

Al principio, la actividad muestra el título predeterminado en la barra de acción (es decir, se establece automáticamente basándose en la android:label la aplicación android:label .

Al mostrar la lista para el siguiente nivel en la jerarquía, el nombre del elemento al que se hace clic debe convertirse en el título de la barra de acción.

Sin embargo, al presionar Atrás , me gustaría recuperar el título predeterminado original. Esto no es algo que FragmentTransaction sabe, por lo que el título no se restaura.

He leído vagamente sobre FragmentBreadCrumbs , pero esto parece requerir el uso de una vista personalizada. Estoy usando ActionBarSherlock y preferiría no tener mi propia vista de título personalizado.

Cual es la mejor manera de hacer esto? ¿Es posible sin una carga de código cliché y tener que mantener un registro de los títulos que se muestran en el camino?


 protected void showFragment(Fragment f) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.fragment_container, f); ft.addToBackStack(null); ft.commit(); } 

En cada fragmento y cada actividad cambio el título como este. De esta manera el título activo siempre será correcto:

 @Override public void onResume() { super.onResume(); // Set title getActivity().getActionBar() .setTitle(R.string.thetitle); } 

Hay algunos casos en los que onResume no se llama dentro de fragmentos. En algunos de estos casos podemos utilizar:

 public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser) { // Set title getActivity().getActionBar() .setTitle(R.string.thetitle); } } 

Como la respuesta original es bastante antigua, esto podría venir de ayuda también. Como se indica en la documentación, es posible que desee registrar un listener para escuchar los cambios de la pila trasera en la Activity alojamiento:

 getSupportFragmentManager().addOnBackStackChangedListener( new FragmentManager.OnBackStackChangedListener() { public void onBackStackChanged() { // Update your UI here. } }); 

A continuación, identifique la situación en el método de devolución de llamada y establezca un título adecuado, sin tener acceso a la ActionBar de ActionBar del Fragment .

Esta es una solución más elegante, ya que el Fragment no tiene que saber sobre la existencia de ActionBar y Activity es generalmente el lugar que está manejando el backstack por lo que tener manejado allí parece ser más apropiado. Fragment debe ser considerado en todo momento sólo por su propio contenido, no el entorno.

Más información sobre el tema en la documentación .

Deje que la actividad de control haga todo el trabajo de la siguiente manera:

Escuche los eventos backstack (en onCreate () de la actividad):

 // Change the title back when the fragment is changed getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { Fragment fragment = getFragment(); setTitleFromFragment(fragment); } }); 

Obtenga el fragmento actual del contenedor:

 /** * Returns the currently displayed fragment. * @return * Fragment or null. */ private Fragment getFragment() { Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container); return fragment; } 

Establezca el fragmento dentro de la vista de contenido:

 private void setFragment(Fragment fragment, boolean addToBackStack) { // Set the activity title setTitleFromFragment(fragment); . . . } 

Warpzit tiene razón. Esto también resuelve el problema del título cuando se cambia la orientación del dispositivo. Además, si utilizas el soporte v7 para la barra de acción, puedes obtener la barra de acción de un fragmento como este:

 @Override public void onResume() { super.onResume(); ((ActionBarActivity)getActivity()).getSupportActionBar().setTitle("Home"); } 

Lo mejor es dejar que el sistema operativo haga todo el trabajo posible. Suponiendo que cada fragmento se nombra adecuadamente usando .addToBackStack ("title"), entonces puede anular algo como esto para lograr el comportamiento deseado:

 // this example uses the AppCompat support library // and works for dynamic fragment titles @Override public void onBackPressed() { FragmentManager fragmentManager = getSupportFragmentManager(); int count = fragmentManager.getBackStackEntryCount(); if (count <= 1) { finish(); } else { String title = fragmentManager.getBackStackEntryAt(count-2).getName(); if (count == 2) { // here I am using a NavigationDrawer and open it when transitioning to the initial fragment // a second back-press will result in finish() being called above. mDrawerLayout.openDrawer(mNavigationDrawerFragment.getView()); } super.onBackPressed(); Log.v(TAG, "onBackPressed - title="+title); getSupportActionBar().setTitle(title); } } 

Utilizo una solución similar al enfoque de Lee , pero reemplazando el método onBackStackChanged() lugar.

Primero establecí el nombre del fragmento al agregar la transacción a la pila trasera.

 getSupportFragmentManager().beginTransaction() .replace(R.id.frame_content, fragment) .addToBackStack(fragmentTitle) .commit(); 

A continuación, anular el método onBackStackChanged() y llamar a setTitle() con el último nombre de entrada backstack.

 @Override public void onBackStackChanged() { int lastBackStackEntryCount = getSupportFragmentManager().getBackStackEntryCount() - 1; FragmentManager.BackStackEntry lastBackStackEntry = getSupportFragmentManager().getBackStackEntryAt(lastBackStackEntryCount); setTitle(lastBackStackEntry.getName()); } 

Método Fragmentos de uso:

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 

Se llama en cada apariencia de Fragmento, pero onResume no lo es.

El mejor enfoque es hacer uso del método de OnBackStackChangedListener proporcionado por android enBackStackChanged ().

Digamos que tenemos un cajón de navegación con 4 opciones a las que el usuario puede navegar. En ese caso tendremos 4 fragmentos. Vamos a ver el código primero y luego voy a explicar el funcionamiento.

  private int mPreviousBackStackCount = 0; private String[] title_name = {"Frag1","Frag2","Frag3","Frag4"}; Stack<String> mFragPositionTitleDisplayed; public class MainActivity extends ActionBarActivity implements FragmentManager.OnBackStackChangedListener @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); .... .... .... getSupportFragmentManager().addOnBackStackChangedListener(this); mFragPositionTitleDisplayed = new Stack<>(); } public void displayFragment() { Fragment fragment = null; String title = getResources().getString(R.string.app_name); switch (position) { case 0: fragment = new Fragment1(); title = title_name[position]; break; case 1: fragment = new Fragment2(); title = title_name[position]; break; case 2: fragment = new Fragment3(); title = title_name[position]; break; case 3: fragment = new Fragment4(); title = title_name[position]; break; default: break; } if (fragment != null) { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.container_body, fragment) .addToBackStack(null) .commit(); getSupportActionBar().setTitle(title); } } @Override public void onBackStackChanged() { int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount(); if(mPreviousBackStackCount >= backStackEntryCount) { mFragPositionTitleDisplayed.pop(); if (backStackEntryCount == 0) getSupportActionBar().setTitle(R.string.app_name); else if (backStackEntryCount > 0) { getSupportActionBar().setTitle(mFragPositionTitleDisplayed.peek()); } mPreviousBackStackCount--; } else{ mFragPositionTitleDisplayed.push(title_name[position]); mPreviousBackStackCount++; } } 

En el código mostrado tenemos el método displayFragment (). Aquí se muestra el fragmento sobre la base de la opción elegida desde el cajón de navegación. La posición de la variable corresponde a la posición del elemento pulsado desde el ListView o RecyclerView en el cajón de navegación. Configuré el título de la barra de acciones de acuerdo con getSupportActionBar.setTitle (título), donde el título almacena el nombre del título apropiado.

Cada vez que hagamos clic en el elemento del cajón de navegación, se muestra un fragmento dependiendo del elemento que se ha hecho clic en el usuario. Pero en el extremo posterior este fragmento se agrega al backstack y el método onBackStachChanged (), se golpea. Lo que he hecho es que he creado una variable mPreviousBackStackCount y lo inicializado a 0. También he creado una pila adicional que almacenará los nombres de título de la barra de acción. Siempre que agrego un nuevo fragmento al backstack, agrego el nombre del título correspondiente a mi pila creada. En el lado opuesto cuando presiono el botón de retroceso onBackStackChanged () se llama y yo pop el último nombre del título de mi pila y poner el título al nombre derivado por el método peek () de la pila.

Ejemplo:

Digamos que nuestra backstack android está vacía:

Presione Choice 1 desde el cajón nav: se llama onBackStachChanged () y el Fragmento 1 se agrega a backstack android, backStackEntryCount se establece en 1 y Frag1 se empuja a mi pila y el tamaño de mFragPositionTitleDisplayed se convierte en 1.

Presione Choice 2 desde el cajón nav: se llama onBackStachChanged () y el Fragmento 2 se agrega a backstack android, backStackEntryCount se establece en 2 y Frag2 se empuja a mi pila y el tamaño de mFragPositionTitleDisplayed se convierte en 2.

Ahora tenemos 2 elementos tanto en la pila de Android y mi pila. Cuando se pulsa el botón back onBackStackChanged () se llama y el valor de backStackEntryCount es 1. El código introduce la parte if y aparece la última entrada de mi pila. Por lo tanto, la backstack Android tiene sólo 1 fragmento – "Fragmento 1" y mi pila sólo tiene 1 título – "Frag1". Ahora me acaba de mirar () el título de mi pila y establecer la barra de acción a ese título.

Recuerde: Para configurar la acción, utilice peek () y no pop () para que la aplicación se bloquee cuando abra más de 2 fragmentos e intente volver pulsando el botón Atrás.

¡Usted soluciona de bastón con onKeyDown! Tengo un bool mainisopen = true <- MainFragment es visible otro Fragment mainisopen = false

Y aquí está mi código:

 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == false) { mainisopen = true; HomeFrag fragment = new HomeFrag(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.fragmet_cont, fragment); fragmentTransaction.commit(); navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.getMenu().findItem(R.id.nav_home).setChecked(true); navigationView.setNavigationItemSelectedListener(this); this.setTitle("Digi - Home"); //Here set the Title back return true; } else { if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == true) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Wollen sie die App schliessen!"); builder.setCancelable(true); builder.setPositiveButton("Ja!", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { System.exit(1); } }); builder.setNegativeButton("Nein!", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_SHORT).show(); } }); AlertDialog dialog = builder.create(); dialog.show(); return true; } return super.onKeyDown(keyCode, event); } } 

Para actualizar el título de la barra de acciones en la tecla de retroceso. Simplemente poner

GetActivity.setTitle ("title")

Dentro del método onCreateView.

  • Ver ciclo de vida del paginador y del fragmento
  • Haga clic en ListFragment
  • El ERROR sobre DrawerLayout (IllegalArgumentException: Ver android.widget.RelativeLayout no es un cajón deslizante)
  • Android ViewPager: fragmentos superpuestos cuando el ancho de página se establece en 90%
  • Permitir rotación / paisaje en un fragmento
  • Fragmento de Android que se comporta raro
  • Cómo desencadenar onListItemClick en un ListFragment
  • Fragmento onCreate llamado varias veces cuando vuelve a cargar el Fragmento
  • Después de la rotación, la transacción de fragmentos da IllegalStateException
  • Problema de devolución de llamada de diálogo a pantalla completa de Android
  • ¿Cuál es la diferencia entre commit () y commitAllowingStateLoss () en Fragments
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.