web-dev-qa-db-fra.com

Android - Basculer le bouton Précédent de la barre Action vers le bouton de navigation

J'ai le problème suivant:

Je sais comment configurer une barre d’outils pour afficher une icône de bouton Précédent au lieu d’une icône de bouton Burger .

De ceci:
 enter image description here

pour ça:

 enter image description here

en utilisant: getSupportActionBar().setDisplayHomeAsUpEnabled(true);


Maintenant, je veux faire l’action inverse, je veux aller de l’icône du bouton précédent à l’icône du burger:

 enter image description here

jusqu'ici:

 enter image description here

Comment puis-je faire ceci?

Mettre à jour:

@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
    }
}
33
Antonio

Si je suppose que vous utilisez Android.support.v4.widget.DrawerLayout dans votre présentation, cette approche peut fonctionner pour vous; Je n'ai testé que sur API 21, mais étant donné qu'il utilise principalement les bibliothèques de support, il devrait fonctionner (derniers mots célèbres) sur des cibles plus basses ou plus élevées.

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 solution utilise ActionBarDrawerToggle.setDrawerIndicatorEnabled pour basculer la visibilité de l'icône du hamburger et ActionBar.setDisplayHomeAsUpEnabled pour la visibilité du bouton Up, en utilisant essentiellement leurs ressources drawable respectives.

Autres hypothèses

  • Votre thème d'activité s'étend Theme.AppCompat.Light.NoActionBar.
97
ade.akinyede

J'ai trouvé des solutions flexibles dans L'application 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);
    }
}

Donc, l'utilisation est vraiment simple.

setToolbarAsUp(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // onBackPressed();
        // or navigate to parent or some other intent
    }
});
3
Anton Pelykh

vous pouvez changer le bouton de la barre d’action avec:

        getSupportActionBar().setHomeAsUpIndicator(R.drawable.back_button);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
1
Martín Huergo

J'ai essayé certains de ces exemples sur mon application, mais aucun ne semblait fonctionner. J'utilise des fragments et certains d'entre eux doivent montrer l'option retour au lieu de la maison. Voici mon implémentation (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()
}

NOTE: ce sont les méthodes onResume et onStop remplacées à l'intérieur du fragment.

REMARQUE: l'icône hamburger n'apparaît que si la méthode toggle.syncState () est appelée. J'ai passé presque 24 heures à comprendre pourquoi l'icône de la maison n'apparaissait pas.

J'espère que mon post peut aider quelqu'un.

1
alexscmar

La réponse choisie est trop compliquée à mon avis. 

J'ai essayé de le mettre en œuvre et je me suis rendu compte que la ActionBarDrawerToggle n'était pas vraiment utile (c'est peut-être pourquoi il a été supprimé du tutoriel officiel Android concernant Navigation Drawer ): cela ne vous simplifie pas la vie lorsque vous souhaitez coordonner le tiroir de navigation et la barre d’action.

Le problème, c’est que vous n’avez qu’un seul "bouton" de base et deux fonctionnalités différentes: ouvrez le tiroir lorsque vous êtes dans l’écran principal et go up lorsque vous êtes plus bas dans votre écran. app. Passer la barre d'outils en tant que paramètre du constructeur ActionBarDrawerToggle, y ajoute l'icône de menu et appelle openDrawer sur l'événement click. Désormais, si vous souhaitez passer à un événement suivant, vous devez désactiver cette icône spéciale et réactiver la fonctionnalité de retour inhérente de la barre d'action ... qui est toujours un gâchis. 

Donc, si ActionBarDrawerToggle ne vous aide pas (encore, peut-être que quelqu'un trouvera le moyen de le faire), pourquoi l'utiliser en premier lieu? Voici comment le faire sans cela:

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);
}
1
David Refaeli

Les meilleures solutions ne fonctionnaient pas dans ce cas:

  • Une activité et plusieurs fragments
  • Un fragment (SettingsFragment) devrait afficher l'icône de retour au lieu du menu Burger
  • Utilisation de com.google.Android.material.appbar.AppBarLayout, androidx.appcompat.widget.Toolbar et ActionBarDrawerToggle

J'appelle cette méthode dans mon activité onCreate ():

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()
        }
    }
}

Et menuDrawerToggle est la suivante:

menuDrawerToggle = ActionBarDrawerToggle(
        this, drawer_layout, toolbar,
        R.string.navigation_drawer_open,
        R.string.navigation_drawer_close
    ).apply {
        drawer_layout.addDrawerListener(this)
        this.syncState()
    }

Fonctionne comme un charme. Peut-être que ça aide n'importe qui.

1
StefanTo

Essayez d'ajouter ci-dessous le code styleAppTheme à votre activity's theme/style.xml. Votre hamburger icon deviendra back icon avec animation

Condition si vous utilisez l'icône hamburger avec NavigationDrawer et 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>

J'espère que ça aide! ou vous devez simplement le faire avec drawable seulement.

Cochez cette link

0
Shishram

Pour moi, je voulais changer l’icône Burger par une icône Flèche vers l'arrière située à gauche de la barre d’action de Fragment, car j’utilisais un Navigation Drawer. Ajoute également un Menu sur le côté droit.

Dans Main Activity, il est déjà défini - par défaut, lorsque Android Studio crée le tiroir de navigation pour moi - comme ceci:

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();

La question est de savoir comment personnaliser la variable ActionBar dans la variable Fragment. Ainsi, lorsque je vais dans la variable Fragment, elle me montrera la variable ActionBar personnalisée et lorsque l’icône flèche vers l'arrière sera cliquée, elle laissera le fragment et la ActionBar retour au premier état.

Dans Fragment (Mise en œuvre complète):

@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>

 

0
Yahya

-> Si vous avez un tiroir sur homeactivity et initalfragment, vous devez afficher le drawertoggle et après le désagrément intérieur, vous ne voulez pas montrer le nom du tiroir, vous devez afficher le bouton de retour et changer le titre de tous les désagréments comme celui-ci.

  • rendez public votre actionbartoggle dans votre activité.

  • dans votre fragment de maison, écrivez ce code.

    @Override
    
    public void onResume() 
    
    {
        super.onResume();
    
        ((HomeActivity)getActivity()).getSupportActionBar().setTitle("Home");
    
        ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
    
        ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(true);}    
    
  • et dans d'autres fragments écrivez ce code:

         @Override
        public void onResume() 
    {     super.onResume();
            ((HomeActivity)getActivity()).getSupportActionBar().setTitle("My Account");
            ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
            ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
    
  • et dans votre activité principale, écrivez sur backpressed:

    @Override
        public void onBackPressed() 
        {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
    
                getSupportFragmentManager().popBackStackImmediate();
    
            } else {
    
                super.onBackPressed();
    
            }
        }
    
0
Hardik Dudhaiya

Utilisez ceci

getSupportActionBar().setDisplayShowHomeEnabled(true);
0
Ram Prakash Bhat
 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;
        }
    });
0
Dinesh