studio personalizar nombre icono example editar cambiar boton bar agregar actionbar android android-fragments android-actionbar actionbarsherlock

nombre - personalizar action bar android studio



¿Manejando el título de ActionBar con el fragmento de la pila de respaldo? (10)

Tengo una Activity donde cargo en un ListFragment y, al hacer clic, se ListFragment un nivel y se muestra un nuevo tipo de ListFragment , reemplazando el original (usando el método showFragment continuación). Esto se coloca en la pila posterior.

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

Al mostrar la lista para el siguiente nivel en la jerarquía, el nombre del elemento en el que se hizo clic debería convertirse en el título de la barra de acciones.

Sin embargo, al presionar Atrás , me gustaría que se restaure el título predeterminado original. Esto no es algo que FragmentTransaction sepa, 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 personalizada.

Cual es la mejor manera de hacer esto? ¿Es posible sin una carga de código repetitivo y tener que hacer un seguimiento 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(); }


¡Tu bastón Resuelve con onKeyDown! Tengo un bool mainisopen = true <- MainFragment es visible otro fragmento 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); } }


Como la respuesta original es bastante antigua, esto también puede ser de ayuda. Como dice la documentación, uno podría querer registrar un listener para escuchar los cambios en la pila de la Activity alojamiento:

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

Luego, identifique la situación en el método de devolución de llamada y establezca un título apropiado, sin acceder a la ActionBar de ActionBar desde el Fragment .

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

Más sobre el tema en la documentation .


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

Escuche los eventos de backstack (en onCreate () de 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; }

Establecer el fragmento dentro de la vista de contenido:

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


El mejor enfoque es hacer uso del método proporcionado por Android Interface OnBackStackChangedListener onBackStackChanged ().

Digamos que tenemos un cajón de navegación con 4 opciones para que el usuario pueda navegar. En ese caso, tendremos 4 fragmentos. Veamos primero el código y luego 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 que se muestra, tenemos el método displayFragment (). Aquí despliego el fragmento sobre la base de la opción elegida desde el cajón de navegación. La posición variable corresponde a la posición del elemento al que se hace clic desde ListView o RecyclerView en el panel de navegación. Establecí el título de la barra de acciones en consecuencia con getSupportActionBar.setTitle (título), donde el título almacena el nombre del título apropiado.

Cada vez que hacemos clic en el elemento del panel de navegación, se muestra un fragmento según el elemento al que se haya hecho clic. Pero en el lado de la parte posterior este fragmento se agrega a la backstack y se golpea el método onBackStachChanged (). Lo que he hecho es que he creado una variable mPreviousBackStackCount y la inicialicé en 0. También he creado una pila adicional que almacenará los nombres de los títulos de la barra de acciones. Cada vez que agrego un nuevo fragmento a la backstack, agrego el nombre del título correspondiente a mi pila creada. En el lado opuesto cada vez que presiono el botón Atrás enBackStackChanged () se llama y saco el último nombre del título de mi pila y establezco el título para el nombre derivado por el método peek () de la pila.

Ejemplo:

Digamos que nuestra backstack android está vacía:

Presione Opción 1 en el cajón de navegación: se llama a OnBackStachChanged () y el Fragmento 1 se agrega a la backstack de Android, BackStackEntryCount se establece en 1 y Frag1 se envía a mi pila y el tamaño de mFragPositionTitleDisplayed se convierte en 1.

Presione Opción 2 desde el cajón de navegación: se llama a OnBackStachChanged () y el Fragmento 2 se agrega a la backstack de Android, BackStackEntryCount se establece en 2 y Frag2 se envía a mi pila y el tamaño de mFragPositionTitleDisplayed se convierte en 2.

Ahora tenemos 2 elementos tanto en la pila de Android como en mi pila. Cuando presiona el botón Atrás en BackPackStackChanged () se llama y el valor de BackStackEntryCount es 1. El código ingresa la parte if y saca la última entrada de mi pila. Entonces, la backstack de Android tiene solo 1 fragmento - "Fragmento 1" y mi pila tiene solo 1 título - "Frag1". Ahora solo miro () el título de mi pila y configuré la barra de acción para ese título.

Recuerde: para configurar el título del juego de acción use peek () y no pop (), su aplicación se bloqueará cuando abra más de 2 fragmentos e intente retroceder presionando el botón Atrás.


En cada fragmento y cada actividad, cambio el título de esta manera. 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 donde onResume no se llama dentro de fragmentos. En algunos de estos casos, podemos usar:

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


Lo mejor es dejar que el SO haga tanto trabajo como sea posible. Suponiendo que cada fragmento se nombra adecuadamente usando .addToBackStack ("título"), entonces puede anular enBackPressed algo así 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); } }


Para actualizar el título de la barra de acciones en la retroceso, presione. Simplemente ponlo

getActivity.setTitle ("título")

en el método onCreateView.


Use el método Fragments:

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

Se invoca en cada aspecto de Fragmento, pero onResume no.


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

Primero configuro el nombre del fragmento al agregar la transacción a la pila posterior.

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

Luego onBackStackChanged() método onBackStackChanged() y llamo a setTitle() con el último nombre de la entrada de backstack.

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


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

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