it-swarm.com.de

Android - Umschalten der ActionBar-Schaltfläche auf die Navigationsschaltfläche

Ich habe folgendes Problem:

Ich weiß, wie man eine Symbolleiste so einrichtet, dass ein Zurück-Button-Symbol anstelle eines Burger-Button-Symbols angezeigt wird.

Davon:
 enter image description here

zu diesem:

 enter image description here

mit: getSupportActionBar().setDisplayHomeAsUpEnabled(true);


Jetzt möchte ich die umgekehrte Aktion ausführen, ich möchte vom Back-Button-Icon zum Burger-Icon wechseln:

 enter image description here

bis hierhin:

 enter image description here

Wie kann ich das machen?

Update:

@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

Wenn ich davon ausgehe, dass Sie Android.support.v4.widget.DrawerLayout in Ihrem Layout verwenden, funktioniert dieser Ansatz möglicherweise für Sie. Ich habe nur mit API 21 getestet, aber da er hauptsächlich die Unterstützungsbibliotheken verwendet, funktioniert sollte (berühmte letzte Wörter) auf niedrigere oder höhere Ziele.

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.
    }

Die Lösung verwendet ActionBarDrawerToggle.setDrawerIndicatorEnabled zum Umschalten der Sichtbarkeit des Hamburger-Symbols und ActionBar.setDisplayHomeAsUpEnabled für die Sichtbarkeit der Schaltfläche Up, wobei im Wesentlichen die jeweiligen drawable-Ressourcen verwendet werden.

Andere Annahmen

  • Ihr Aktivitätsthema erweitert Theme.AppCompat.Light.NoActionBar.
97
ade.akinyede

Ich habe in Die Google I/O 2017 Android App flexible Lösungen gefunden.

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

Die Verwendung ist also sehr einfach.

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

sie können die Aktionsleisten-Schaltfläche folgendermaßen ändern:

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

Ich habe einige dieser Beispiele in meiner App ausprobiert, aber keines davon schien zu funktionieren. Ich verwende Fragmente und einige von ihnen müssen die Option "Zurück" anstelle von "Zuhause" zeigen. Hier ist meine Implementierung (in 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()
}

HINWEIS: Dies sind die überschriebenen onResume- und onStop-Methoden im Fragment.

REMARK: Das Symbol hamburger wird nur angezeigt, wenn die toggle.syncState () -Methode aufgerufen wird. Ich habe fast 24 Stunden herausgefunden, warum das Home-Symbol nicht angezeigt wurde.

Hoffe, dass mein Beitrag jemandem helfen kann.

1
alexscmar

Die ausgewählte Antwort ist meiner Meinung nach zu hackig. 

Ich habe versucht, es zu implementieren, und dabei wurde mir klar, dass die ActionBarDrawerToggle eigentlich nicht sinnvoll ist (vielleicht wurde sie deshalb aus dem offiziellen Android-Tutorial bezüglich Navigation Drawer entfernt): es macht Ihr Leben nicht einfacher wenn Sie zwischen der Navigationsleiste und der Aktionsleiste koordinieren möchten.

Das Problem ist, dass Sie nur einen Home-Button haben und dass es 2 verschiedene Funktionen hat - Öffnen Sie die Schublade, wenn Sie sich im Hauptbildschirm befinden, und hoch, wenn Sie es sind weiter unten in Ihrer App. Übergeben Sie die Symbolleiste als Parameter an den Konstruktor ActionBarDrawerToggle, fügt das Menüsymbol hinzu und ruft beim Klickereignis openDrawer auf. Wenn Sie nun zu einem Up-Ereignis wechseln möchten, müssen Sie dieses spezielle Symbol deaktivieren und die inhärente Zurück-Funktionalität der Aktionsleiste wieder aktivieren ... was immer noch ein Durcheinander ist. 

Wenn also ActionBarDrawerToggle Ihnen nicht hilft (doch vielleicht wird jemand einen Weg finden, wo er es tut), warum sollte er das überhaupt verwenden? So machen Sie es ohne:

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

Die Top-Lösungen haben in diesem Fall nicht funktioniert:

  • Eine Aktivität und mehrere Fragmente
  • Ein Fragment (SettingsFragment) sollte anstelle des Burgermenüs das Zurück-Symbol anzeigen
  • Verwenden Sie com.google.Android.material.appbar.AppBarLayout, androidx.appcompat.widget.Toolbar und ActionBarDrawerToggle

Ich nenne diese Methode in onCreate () meiner Activity:

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

Und menuDrawerToggle ist folgendes:

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

Klappt wunderbar. Vielleicht hilft es jedem.

1
StefanTo

Fügen Sie unten den Code von styleAppTheme zu Ihrem activity's theme/style.xml hinzu. Der hamburger icon wird mit animation in back icon geändert. 

Bedingung, wenn Sie das Hamburger-Symbol mit NavigationDrawer und AppCompatActivity/ActionBarActivity verwenden

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

Ich hoffe, es hilft! oder Sie müssen es nur mit Drawable tun.

Überprüfen Sie diesen Link

0
Shishram

Für mich wollte ich das Symbol Burger durch ein Symbol Zurückpfeil auf der linken Seite von Fragments ActionBar ändern, da ich einen Navigation Drawer verwende. Hinzufügen eines Menü auf der rechten Seite.

In Main Activity ist diese Einstellung bereits festgelegt - standardmäßig, wenn Android Studio den Navigation Drawer für mich erstellt - wie folgt:

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

Die Frage ist, wie man ActionBar in Fragment anpassen kann. Wenn ich also zum Fragment gehe, wird mir der angepasste ActionBar und wann der Zurückpfeil) angezeigt-Icon wird angeklickt, das Fragment wird verlassen, und ActionBar sollte in den ersten Zustand zurückkehren.

In Fragment (vollständige Implementierung):

@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

-> Wenn Sie eine Schublade zu Homeaktivität und Anfangsfragment haben, müssen Sie den Drawertoggle anzeigen, und nach innerem Fragement möchten Sie nicht den Schubladen-Namen der Schublade zeigen, müssen Sie den Zurück-Button anzeigen und den Titel aller Fragement-Einstellungen so ändern.

  • machen Sie Ihren Actionbartoggle in Ihrer Aktivität öffentlich.

  • schreiben Sie diesen Code in Ihr Heimatfragment.

    @Override
    
    public void onResume() 
    
    {
        super.onResume();
    
        ((HomeActivity)getActivity()).getSupportActionBar().setTitle("Home");
    
        ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
    
        ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(true);}    
    
  • und in anderen Fragmenten diesen Code schreiben:

         @Override
        public void onResume() 
    {     super.onResume();
            ((HomeActivity)getActivity()).getSupportActionBar().setTitle("My Account");
            ((HomeActivity)getActivity()).actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
            ((HomeActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
    
  • und schreiben Sie in Ihrer Hauptaktivität auf backpressed:

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

Benutze das

getSupportActionBar().setDisplayShowHomeEnabled(true);
0
 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