studio - Android: cambie el botón Atrás de ActionBar al botón de navegación
programar boton atras android studio (11)
-> Si tiene un cajón de actividad doméstica y fragmento inicial, debe mostrar el conmutador de cajón y, después de la fragmentación interna, no desea mostrar el nombre del cajón del cajón, debe mostrar el botón Atrás y cambiar el título de toda la fragmentación de esta manera.
-
Haz que tu actionbartoggle sea público en tu actividad.
-
en el fragmento de tu casa escribe este código.
@Override public void onResume() { super.onResume(); ((HomeActivity)getActivity()).getSupportActionBar().setTitle("Home"); ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(true);}
-
y en otros fragmentos escribe este código:
@Override public void onResume() { super.onResume(); ((HomeActivity)getActivity()).getSupportActionBar().setTitle("My Account"); ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(false); ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); }
-
y en su actividad principal escriba en backpressed:
@Override public void onBackPressed() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportFragmentManager().popBackStackImmediate(); } else { super.onBackPressed(); } }
Estoy teniendo el siguiente problema:
Sé cómo configurar una barra de herramientas para mostrar un icono de botón de retroceso en lugar de un icono de botón de hamburguesa.
De esto:
a esto:
usando:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Ahora, quiero hacer la acción inversa, quiero pasar del icono del botón Atrás al icono de la hamburguesa:
hacia aqui:
¿Cómo puedo hacer esto?
Actualizar:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
private void enableViews(boolean enable) {
if(enable) {
// Enables back button icon
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
// TODO: Enables burger icon
}
}
Encontré soluciones flexibles en la aplicación de Android Google I / O 2017 .
public Toolbar getToolbar() {
if (mToolbar == null) {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
mToolbar.setNavigationContentDescription(R.string.navdrawer_description_a11y);
mToolbarTitle = (TextView) mToolbar.findViewById(R.id.toolbar_title);
if (mToolbarTitle != null) {
int titleId = getNavigationTitleId();
if (titleId != 0) {
mToolbarTitle.setText(titleId);
}
}
// We use our own toolbar title, so hide the default one
getSupportActionBar().setDisplayShowTitleEnabled(false);
}
}
return mToolbar;
}
/**
* @param clickListener The {@link android.view.View.OnClickListener} for the navigation icon of
* the toolbar.
*/
protected void setToolbarAsUp(View.OnClickListener clickListener) {
// Initialise the toolbar
getToolbar();
if (mToolbar != null) {
mToolbar.setNavigationIcon(R.drawable.ic_up);
mToolbar.setNavigationContentDescription(R.string.close_and_go_back);
mToolbar.setNavigationOnClickListener(clickListener);
}
}
Entonces el uso es realmente simple.
setToolbarAsUp(new View.OnClickListener() {
@Override
public void onClick(View v) {
// onBackPressed();
// or navigate to parent or some other intent
}
});
He estado probando algunos de estos ejemplos en mi aplicación, pero ninguno de ellos parecía funcionar. Estoy usando fragmentos y algunos de ellos deben mostrar la opción de retroceso en lugar de inicio. Aquí está mi implementación (en Kotlin):
override fun onResume() {
super.onResume()
var drawerLayout: DrawerLayout = activity.findViewById(R.id.drawer_layout)
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
var actionBar = (activity as MainActivity).supportActionBar
actionBar!!.setDisplayHomeAsUpEnabled(true)
var toggle= (activity as MainActivity).drawerToggle
toggle.isDrawerIndicatorEnabled = false
toggle.setToolbarNavigationClickListener { v -> activity.onBackPressed() }
}
override fun onStop() {
super.onStop()
var drawerLayout: DrawerLayout = activity.findViewById(R.id.drawer_layout)
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
var actionBar = (activity as MainActivity).supportActionBar
actionBar!!.setDisplayHomeAsUpEnabled(false)
var toggle= (activity as MainActivity).drawerToggle
toggle.setToolbarNavigationClickListener {null}
toggle.syncState()
}
NOTA: estos son los métodos onResume y onStop anulados dentro del fragmento.
OBSERVACIÓN: el icono de hamburguesa solo aparecerá si se llama al método toggle.syncState (). Llevo casi 24 horas descubriendo por qué no se muestra el ícono de inicio.
Espero que mi publicación pueda ayudar a alguien.
Intente agregar el siguiente código de
style
AppTheme
al
activity''s theme/style.xml
su
activity''s theme/style.xml
hará que su
hamburger icon
back icon
con
animation
.
Condición
si está utilizando el icono de hamburguesa con
NavigationDrawer
y
AppCompatActivity/ActionBarActivity
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="windowActionBar">false</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">@android:color/white</item>
</style>
¡Espero que ayude! o solo tienes que hacerlo solo con dibujable.
Mira este link
La respuesta seleccionada es demasiado hacky en mi opinión.
Intenté implementarlo, y al hacerlo me di cuenta de que en realidad no hay un buen uso para el
ActionBarDrawerToggle
(tal vez es por eso que se eliminó del tutorial oficial de Android sobre
Navigation Drawer
): no te hace la vida más fácil cuando quieres coordinar entre el cajón de navegación y la barra de acción.
El problema es que solo tiene 1 "botón" de inicio y que tiene 2 funcionalidades diferentes:
abra el cajón
cuando esté en la pantalla principal y
suba
cuando esté más abajo en su aplicación.
Al pasar la barra de herramientas como parámetro al constructor
ActionBarDrawerToggle
, se le agrega el ícono de menú y se llama al evento openDrawer al hacer clic.
Ahora, si desea cambiar a un evento activo, debe desactivar este icono especial y volver a habilitar la funcionalidad de respaldo inherente de la barra de acción ... que sigue siendo un desastre.
Entonces, si
ActionBarDrawerToggle
no te ayuda (aún, tal vez alguien
ActionBarDrawerToggle
forma en que lo hace), ¿por qué usarlo en primer lugar?
Aquí se explica cómo hacerlo sin él:
boolean homeShouldOpenDrawer; // flag for onOptionsItemSelected
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// if you''re using NoActionBar theme
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionbar = getSupportActionBar();
// enables the home button with a <-
actionbar.setDisplayHomeAsUpEnabled(true);
// replaces the <- with the menu (hamburger) icon
// (ic_menu should be in every empty project, and can be easily added)
actionbar.setHomeAsUpIndicator(R.drawable.ic_menu);
// I assume your first fragment/state should be main screen, i.e. home = opens drawer
homeShouldOpenDrawer = true;
...
}
private void enableViews(boolean enable) {
if(enable) {
// Enables back button icon
// passing null or 0 brings back the <- icon
getSupportActionBar().setHomeAsUpIndicator(null);
homeShouldOpenDrawer = false;
} else {
// Enables burger icon
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
homeShouldOpenDrawer = true;
}
}
// this is called whenever a selection is made from the action bar
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (homeShouldOpenDrawer) {
drawerLayout.openDrawer(GravityCompat.START);
} else {
onBackPressed();
}
}
return super.onOptionsItemSelected(item);
}
Las mejores soluciones no funcionaron en este caso:
- Una actividad y múltiples fragmentos
- One Fragment (SettingsFragment) debería mostrar el icono de atrás en lugar del menú de hamburguesas
- Usando com.google.android.material.appbar.AppBarLayout, androidx.appcompat.widget.Toolbar y ActionBarDrawerToggle
Llamo a este método en onCreate () de mi Actividad:
private fun initBackStackChangeListener() {
supportFragmentManager.addOnBackStackChangedListener {
val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
if (fragment is SettingsFragment) {
menuDrawerToggle?.isDrawerIndicatorEnabled = false
drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
menuDrawerToggle?.setToolbarNavigationClickListener { onBackPressed() }
supportActionBar?.setDisplayHomeAsUpEnabled(true)
} else {
supportActionBar?.setDisplayHomeAsUpEnabled(false)
drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
menuDrawerToggle?.isDrawerIndicatorEnabled = true
menuDrawerToggle?.toolbarNavigationClickListener = null
menuDrawerToggle?.syncState()
}
}
}
Y menuDrawerToggle es esto:
menuDrawerToggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
).apply {
drawer_layout.addDrawerListener(this)
this.syncState()
}
Funciona de maravilla. Tal vez ayude a alguien.
Para mí, quería cambiar el ícono de
Burger
por un ícono de
Flecha hacia atrás
en el lado izquierdo de la Barra de acciones de
Fragment
mientras uso un
Navigation Drawer
.
También agregando un
menú
en el lado derecho.
En Actividad principal , ya está configurado, de manera predeterminada cuando Android Studio crea el Cajón de navegación para mí, de esta manera:
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
El problema es cómo personalizar la
ActionBar
en el
Fragment
, por lo que cuando vaya al
Fragment
me mostrará la
ActionBar
personalizada y cuando se
ActionBar
en el ícono de la
Flecha hacia atrás
, dejará el fragmento y la
ActionBar
debería volver al primer estado.
En Fragmento ( Implementación Completa ):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); // To show the menu options
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
showActionBar(); // the method to change ActionBar
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// inflate the customized menu which already created in XML
getActivity().getMenuInflater().inflate(R.menu.fragment_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// add implementation when user select an item from the menu
switch (item.getItemId()) {
case R.id.option1:
// do something
return true;
case R.id.option2:
// do something
return true;
case R.id.option3:
// do something
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showActionBar() {
// get the ToolBar from Main Activity
final Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
// get the ActionBar from Main Activity
final ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
// inflate the customized Action Bar View
LayoutInflater inflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.fragment_actionbar, null);
if (actionBar != null) {
// enable the customized view and disable title
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setCustomView(v);
// remove Burger Icon
toolbar.setNavigationIcon(null);
// add click listener to the back arrow icon
v.findViewById(R.id.back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// reverse back the show
actionBar.setDisplayShowCustomEnabled(false);
actionBar.setDisplayShowTitleEnabled(true);
//get the Drawer and DrawerToggle from Main Activity
// set them back as normal
DrawerLayout drawer = getActivity().findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
getActivity(), drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
// All that to re-synchronize the Drawer State
toggle.syncState();
// Implement Back Arrow Icon
// so it goes back to previous Fragment
getActivity().onBackPressed();
}
});
}
}
fragment_actionbar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_horizontal" >
<ImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="@drawable/ic_menu_back"
android:layout_marginLeft="@dimen/_5sdp"
android:layout_alignParentStart="true"
android:layout_marginStart="@dimen/_5sdp" />
</RelativeLayout>
ic_menu_back.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="459"
android:viewportWidth="459">
<path
android:fillColor="#ffffff"
android:pathData="M178.5,140.25v-102L0,216.75l178.5,178.5V290.7c127.5,0,216.75,40.8,280.5,130.05C433.5,293.25,357,165.75,178.5,140.25z"/>
</vector>
fragment_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/border_shadow">
<item
android:id="@+id/option1"
android:title="@string/show_profile"
app:showAsAction="never"/>
<item
android:id="@+id/option2"
android:title="@string/report_pic"
app:showAsAction="never"/>
<item
android:id="@+id/option3"
android:title="@string/delete_pic"
app:showAsAction="never"/>
</menu>
Si supongo que está usando
android.support.v4.widget.DrawerLayout
en su diseño, entonces este enfoque puede funcionar para usted;
Solo probé en
API 21
pero dado que usa principalmente bibliotecas de soporte,
debería
funcionar (últimas palabras famosas) en objetivos inferiores o superiores.
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v4.widget.DrawerLayout
ActionBarDrawerToggle mDrawerToggle;
DrawerLayout drawerLayout;
private boolean mToolBarNavigationListenerIsRegistered = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
// Get DrawerLayout ref from layout
drawerLayout = (DrawerLayout)findViewById(R.id.drawer);
// Initialize ActionBarDrawerToggle, which will control toggle of hamburger.
// You set the values of R.string.open and R.string.close accordingly.
// Also, you can implement drawer toggle listener if you want.
mDrawerToggle = new ActionBarDrawerToggle (this, drawerLayout, mToolbar, R.string.open, R.string.close);
// Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(mDrawerToggle);
// Calling sync state is necessary to show your hamburger icon...
// or so I hear. Doesn''t hurt including it even if you find it works
// without it on your test device(s)
mDrawerToggle.syncState();
}
/**
* To be semantically or contextually correct, maybe change the name
* and signature of this function to something like:
*
* private void showBackButton(boolean show)
* Just a suggestion.
*/
private void enableViews(boolean enable) {
// To keep states of ActionBar and ActionBarDrawerToggle synchronized,
// when you enable on one, you disable on the other.
// And as you may notice, the order for this operation is disable first, then enable - VERY VERY IMPORTANT.
if(enable) {
//You may not want to open the drawer on swipe from the left in this case
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// Remove hamburger
mDrawerToggle.setDrawerIndicatorEnabled(false);
// Show back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// when DrawerToggle is disabled i.e. setDrawerIndicatorEnabled(false), navigation icon
// clicks are disabled i.e. the UP button will not work.
// We need to add a listener, as in below, so DrawerToggle will forward
// click events to this listener.
if(!mToolBarNavigationListenerIsRegistered) {
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Doesn''t have to be onBackPressed
onBackPressed();
}
});
mToolBarNavigationListenerIsRegistered = true;
}
} else {
//You must regain the power of swipe for the drawer.
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
// Remove back button
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
// Show hamburger
mDrawerToggle.setDrawerIndicatorEnabled(true);
// Remove the/any drawer toggle listener
mDrawerToggle.setToolbarNavigationClickListener(null);
mToolBarNavigationListenerIsRegistered = false;
}
// So, one may think "Hmm why not simplify to:
// .....
// getSupportActionBar().setDisplayHomeAsUpEnabled(enable);
// mDrawer.setDrawerIndicatorEnabled(!enable);
// ......
// To re-iterate, the order in which you enable and disable views IS important #dontSimplify.
}
La solución usa
ActionBarDrawerToggle.setDrawerIndicatorEnabled
para alternar la visibilidad del ícono de hamburguesa y
ActionBar.setDisplayHomeAsUpEnabled
para la visibilidad del botón
Arriba
, esencialmente haciendo uso de sus recursos
drawable
respectivos.
Otros supuestos
-
Su tema de actividad extiende
Theme.AppCompat.Light.NoActionBar
.
Utilizar este
getSupportActionBar().setDisplayShowHomeEnabled(true);
puedes cambiar el botón de la barra de acción con:
getSupportActionBar().setHomeAsUpIndicator(R.drawable.back_button);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final Toolbar toolbar = (Toolbar) findViewById(R.id.actionbar);
toolbar.setTitle(Html.fromHtml("<font color=#ffffff>" + getString(R.string.print_s) + "</font>"));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.menu_icon));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DetailActivity.this.finish();
}
});
toolbar.inflateMenu(R.menu.fav);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
item.setIcon(R.drawable.back_icon)
return true;
}
return false;
}
});