para notificaciones navegacion home funcion estado configurar color cambiar botones boton barra aplicacion android android-fragments navigation

android - notificaciones - Barra de herramientas-Cambiar del cajón al botón Atrás con solo una Actividad



cambiar funcion boton home android (5)

Debería funcionar incluso para la última API 24 .

En su actividad onCreate() haga esto:

final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); final DrawerLayout drawer = (DrawerLayout) view.findViewById(R.id.drawer_layout); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); final View.OnClickListener originalToolbarListener = toggle.getToolbarNavigationClickListener(); getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { toggle.setDrawerIndicatorEnabled(false); toggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getSupportFragmentManager().popBackStack(); } }); } else { toggle.setDrawerIndicatorEnabled(true); toggle.setToolbarNavigationClickListener(originalToolbarListener); } } });

He estado buscando durante un tiempo cómo cambiar entre el icono de apertura / cierre del cajón (pasando de una hamburguesa a la flecha) a una simple flecha hacia atrás. Mi aplicación en este momento solo tiene una actividad que alterna entre varios fragmentos. En un momento, quiero hacer la transición entre uno de los fragmentos principales (es decir, uno de los fragmentos en el cajón) a un fragmento que está jerárquicamente debajo del fragmento anterior (es decir, un fragmento "Agregar nuevo"). En este nuevo fragmento, quiero que la barra de herramientas muestre el botón Atrás en lugar del botón del cajón.

He estado buscando e intentando diferentes soluciones durante bastante tiempo. Aquí están los más notables:

Por el momento, estoy pensando en un método largo y arduo para crear un ícono personalizado que oculto y muestro (y oculto / muestro el ícono del cajón nativo). Sin embargo, ¿hay una mejor manera de cambiar entre el cajón y los botones de atrás?

Como una pregunta adicional relacionada, he estado mirando los documentos de Material Design, y algunos ejemplos tienen una X en la esquina superior izquierda. ¿Qué tan diferente es implementarlo que implementar los botones de cajón contra respaldo / arriba?

Gracias ~

Editar:

Puedo descubrir cómo reemplazar el ícono, pero ¿cómo obtendría el evento de clic?

Hasta ahora, esta fue mi mejor ventaja:

Lo que he intentado ahora:

  • Desactivado el DrawerToggle cuando sea necesario (es decir, mDrawerToggle.setDrawerIndicatorEnabled(useDrawer); )
  • Se han agregado registros en onPtionsItemSelected en mi NavigationDrawerFragment, mi actividad, así como el DialogFragment que estoy probando, que se ejecuta si item.getItemId() == android.R.id.home es verdadero. Ninguna de estas declaraciones de registro se apaga

Para un mejor contexto, ahora tengo un fragmento de pantalla completa que agrega un botón "Guardar" al menú y cambia el icono del cajón a una "X". El fragmento puede obtener el evento de guardar el menú, pero ni siquiera la actividad y el cajón pueden obtenerse cuando se toca la X.

Edit2:

Según lo solicitado, aquí hay un código. Tenga en cuenta que todo esto es de este repositorio Github , en el que estoy trabajando activamente (tenga en cuenta que tengo algunas funciones inútiles aquí y allá de las pruebas rápidas).

ActivityMain :

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Add the toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); if (mToolbar != null) { setSupportActionBar(mToolbar); } // Initialize the drawer mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer); // Set up the drawer mNavigationDrawerFragment.setUp( R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar); // TODO: Check if this helps to catch the main toolbar button click getSupportActionBar().setDisplayShowHomeEnabled(true); // Get the titles for the Toolbar mTitles = getResources().getStringArray(R.array.drawer_items); mDrawerPosition = -1; if (savedInstanceState == null) { // If there was no saved position, then the default, starting position should be used forceChangeItemSelected(0); } else { // Otherwise, get the saved position from the bundle int position = savedInstanceState.getInt(KEY_DRAWERPOS); mNavigationDrawerFragment.setSelectedItem(position); // Title needs to be re-set getSupportActionBar().setTitle(mTitles[position]); } // If I include the below bit, then the DrawerToggle doesn''t function // I don''t know how to switch it back and forth mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(LOG_TAG, "Navigation was clicked"); } }); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. Log.d(LOG_TAG, "Activity responding to menu click..."); if(item.getItemId() == android.R.id.home) Log.d(LOG_TAG, "Activity got it...."); // If the fragment is supposed to handle things, then let it if(mIsFragmentHandlingMenus) return false; int id = item.getItemId(); if(id == R.id.save) { // This isn''t implemented! If chosen, then there''s a bug! Log.e(LOG_TAG, "onOptionsItemSelected: Save was selected!"); } return super.onOptionsItemSelected(item); } @Override public void fragmentHandlingMenus(boolean isFragmentHandlingMenus) { // Simply store the setting mIsFragmentHandlingMenus = isFragmentHandlingMenus; // Toggle the drawer as necessary mNavigationDrawerFragment.toggleDrawerUse(!isFragmentHandlingMenus); }

NavigationDrawerFragment :

public void toggleDrawerUse(boolean useDrawer) { // Enable/Disable the icon being used by the drawer mDrawerToggle.setDrawerIndicatorEnabled(useDrawer); // TODO: Enable/Disable the drawer even being able to open/close } @Override public boolean onOptionsItemSelected(MenuItem item) { Log.d(LOGTAG, "Drawer responding to menu click..."); if(item.getItemId() == android.R.id.home) Log.d(LOGTAG, "Drawer got it...."); if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); }

GoalAdderFragment :

@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Allow this fragment to handle toolbar menu items setHasOptionsMenu(true); // Set up the toolbar ((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); ((ActionBarActivity) getActivity()).getSupportActionBar().setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel); ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(getResources().getString(R.string.title_addgoal)); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // Cache the Activity as the frag handler if necessary if(mFragHandler == null) mFragHandler = (TransactionHandler.FragmentTransactionHandler) getActivity(); // Tell the Activity to let fragments handle the menu events mFragHandler.fragmentHandlingMenus(true); } @Override public void onDetach() { super.onDetach(); // Tell the Activity that it can now handle menu events once again mFragHandler.fragmentHandlingMenus(false); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.save_menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { Log.d(LOGTAG, "Item id: " + item.getItemId() + " | Save id: " + R.id.save); Toast.makeText(getActivity(), "Fragment activated!", Toast.LENGTH_SHORT).show(); switch (item.getItemId()) { case R.id.save: return true; case android.R.id.home: return true; default: break; } return false; }

Solución:

Esta es la última solución en la que terminé, con la ayuda de la respuesta aceptada a continuación:

NavigationDrawerFragment :

private View.OnClickListener mOriginalListener; public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) { /* Rest of setting up code */ // Save the default listener after setting everything else up mOriginalListener = mDrawerToggle.getToolbarNavigationClickListener(); } // Tells the toolbar+drawer to switch to the up button or switch back to the normal drawer public void toggleDrawerUse(boolean useDrawer) { // Enable/Disable the icon being used by the drawer mDrawerToggle.setDrawerIndicatorEnabled(useDrawer); // Switch between the listeners as necessary if(useDrawer) mDrawerToggle.setToolbarNavigationClickListener(mOriginalListener); else mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(), "Custom listener", Toast.LENGTH_SHORT).show(); } }); }


La respuesta de @matusalem funciona muy bien. Solo tenía que añadir un poco: tenga cuidado porque también se puede abrir el cajón deslizando el dedo desde el lado izquierdo de la pantalla. Para algunos, esto puede ser deseado, pero para mí estaba desactivando el cajón porque no tenía sentido en ningún fragmento, sino en mi fragmento principal. El deslizamiento se desactiva fácilmente aquí - Cajón de navegación - desactivar deslizar

Esto probablemente pertenece a un comentario de la respuesta, pero no tengo suficiente reputación. Mis disculpas.


Pon este código en onCreate() de tu Activity . Funciona bien para mi Incluso utilizando compileSdk 23 y superior.

drawer = (DrawerLayout) findViewById(R.id.drawer_layout); final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if(toolbar != null) { toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); toggle.syncState(); drawer.setDrawerListener(toggle); getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); // show back button toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); } else { //show hamburger getSupportActionBar().setDisplayHomeAsUpEnabled(false); toggle.syncState(); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { drawer.openDrawer(GravityCompat.START); } }); } } });


Probablemente no sea eso lo que le gustaría escuchar, pero incluso desde un punto de vista conceptual, iría a una nueva actividad en lugar de a un fragmento.

Su actividad principal está estrictamente vinculada al cajón, por lo que cargar un nuevo fragmento sin acceso al cajón no tiene sentido para mí (pero siéntase libre de esperar otras respuestas si lo cree). Una nueva actividad resolvería ambos problemas, ya que no tendría cajón y podría ser un hijo del principal.

Tu pregunta lateral parece perfecta también. Una actividad "Agregar nuevo" podría encajar muy bien en el patrón visual de "diálogo a pantalla completa" de las pautas. Ver:

http://www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs

Este patrón tiene un "guardar", un botón positivo en la parte superior derecha y una X. Conceptualmente, el botón X es para cancelar / abortar un proceso, en lugar de navegar hacia atrás. Significa que estás descartando algo sin permitir que suceda ninguna acción. Esto encaja bien con lo que quieres hacer.

Desde el punto de vista del diseño, se crea fácilmente mediante una nueva Activity que puede mantenerse encima de otras. Además, si el punto de los fragmentos es básicamente poder representar dos o más a la vez en tabletas y pantallas más grandes, de nuevo, no estaría tan contento con un fragmento viejo a mi izquierda y un fragmento "Agregar nuevo" a la derecha .

Más bien, en tabletas, elegiría un diálogo flotante, como lo sugieren las directrices.

http://www.google.com/design/spec/components/dialogs.html#dialogs-confirmation-dialogs

Así que la actividad de pantalla completa con un botón X para teléfonos y un diálogo flotante (con botones en la parte inferior) para tabletas. Esto, para mí, es el enfoque más coherente con las directrices.

Recomiendo leer todo el enlace. En la diferencia entre <- y X,

La X difiere de una flecha hacia arriba, que se usa cuando el estado de la vista se guarda constantemente o cuando las aplicaciones tienen capacidades de borrador o autoguardado. Por ejemplo, una flecha hacia arriba se usa en Configuración porque todos los cambios se confirman de inmediato.

Y también

Al tocar la X en este ejemplo de configuración, se descartarán todos los cambios. Los cambios se guardarán solo al tocar Guardar.


Tuve el mismo problema al cambiar entre el menú de hamburguesas y la flecha hacia atrás dentro de la misma actividad al cambiar los fragmentos. Aquí está mi solución de trabajo, espero que ayude a alguien.

Oyente dentro de tu actividad:

private View.OnClickListener toolbarMenuListener = new View.OnClickListener() { @Override public void onClick(View v) { //will be called only if toggle.setDrawerIndicatorEnabled(false); ! Log.v(tag,"toggle onClick:"+v.getId()+" android.R.id.home:"+android.R.id.home); onBackPressed(); } };

Código onCreate () algo como:

... ... setSupportActionBar(toolbar); toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); //set listener so you know when back on arrow is pressed toggle.setToolbarNavigationClickListener(toolbarMenuListener); ... ...

Parte con la que está interesado con los comentarios (la clase devuelta es una de la clase mía, puede establecerse como nula):

/** * Method to set up action bar drawer. * @param enableBackDrawerIcon set true if want to show drawer back arrow, * false to show hamburger menu. * @param title shown next to drawer icon */ public BaseMenusActivity drawerSetupToggle(boolean enableBackDrawerIcon, String title) { //NOTE: order of methods call is important! // If you change order order of setDrawerIndicatorEnabled and setDisplayHomeAsUpEnabled // method calls it won''t work, weird bugs will happen (like no icon at all) if(enableBackDrawerIcon){ Log.v(tag,"show drawer back icon"); //hides hamburger menu and enables View.OnClickListener to be called toggle.setDrawerIndicatorEnabled(false); //show back arrow if(getSupportActionBar()!=null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); } else { Log.v(tag,"show hamburger menu"); //hide back arrow if(getSupportActionBar()!=null) getSupportActionBar().setDisplayHomeAsUpEnabled(false); //shows hamburger menu and prevents View.OnClickListener to be called toggle.setDrawerIndicatorEnabled(true); } setTitle(title); return this; }

NOTA : ¡el orden de los métodos invocados es importante! Sería mejor si pudiera escribirlo en 2 líneas como esta, pero NO FUNCIONARÁ (al menos para mí):

toggle.setDrawerIndicatorEnabled(!enableBackDrawerIcon); getSupportActionBar().setDisplayHomeAsUpEnabled(enableBackDrawerIcon);

Si le interesa saber por qué el orden de los métodos desorientan las cosas, investigue la implementación de esos métodos.