web-dev-qa-db-fra.com

Barre d'outils Android + ActionBarDrawerToggle non modifié en flèche

Je me bats avec la barre d'outils et le tiroir. J'essaie de faire basculer le hamburger en flèche lorsque j'ajoute un nouveau fragment au pile, mais il n'y a aucun moyen de le faire.

Peut-être que je manque quelque chose mais je ne pouvais pas trouver un moyen. Quelqu'un a eu le même problème?

C'est la déclaration:

mDrawerToggle = new ActionBarDrawerToggle(
            getActivityCompat(),                    /* Host Activity */
            mDrawerLayout,                    /* DrawerLayout object */
            ((BaseActivity) getActivityCompat()).getToolbar(),
            R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
            R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
    )

C'est la fonction que j'appelle lorsqu'un fragment est ajouté à la pile arrière

public void setToggleState(boolean isEnabled) {
    if (mDrawerLayout == null)
        return;

    if (isEnabled) {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
    } else {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }
    mDrawerToggle.syncState();
}
20
Marcel

Je pense que tout ce que vous avez à faire est de supprimer le troisième argument. Ainsi:

mDrawerToggle = new ActionBarDrawerToggle(
     getActivityCompat(),              /* Host Activity */
     mDrawerLayout,                    /* DrawerLayout object */
     // ((BaseActivity) getActivityCompat()).getToolbar(), <== delete this argument
     R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
     R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
    );

Peut que ça aide.

31
hata

J'ai eu le même problème. Ma solution était la suivante:

Assurez-vous que votre activité implémente onBackStackChangedListener. Dans onCreate de vos activités, je définis l'écouteur backstack et la barre d'outils.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mFm = getFragmentManager();
    mFm.addOnBackStackChangedListener(this);

    // Setup toolbar
    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    mToolbar.setVisibility(View.VISIBLE);
    setSupportActionBar(mToolbar);

    // Setup drawer toggle
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.menu_open, R.string.menu_close);
    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportActionBar().setHomeButtonEnabled(true);
    mDrawerToggle.syncState();

    // Setup initial fragment
    if (savedInstanceState == null) {
        mCurrentFragment = DashboardFragment.newInstance();
        mFm.beginTransaction().add(CONTAINER_ID, mCurrentFragment).commit();
    }
}

Rappelez-vous également de définir:

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

Maintenant, la magie se passe dans onBackStackChanged (). Définissez setDrawerIndicatorEnabled sur true pour le fragment situé en haut et setDisplayHomeAsUpEnabled sur false pour ce fragment. Inverse pour les autres. J'ai également dû appeler syncState, sinon le hamburger ne réapparaîtrait pas:

@Override
public void onBackStackChanged() {
    mDrawerToggle.setDrawerIndicatorEnabled(mFm.getBackStackEntryCount() == 0);
    getSupportActionBar().setDisplayHomeAsUpEnabled(mFm.getBackStackEntryCount() > 0);
    mDrawerToggle.syncState();
}
12
hordurh

La réponse de @ hata est parfaite dans la plupart des cas.

Mais en réalité, vous ne vous êtes pas trompé en utilisant la barre d’outils comme argument du constructeur ActionBarDrawerToggle(...).

Bien sûr, cela n’a aucun sens de le faire si vous utilisez la valeur stock ToolbarAppCompatActivity en utilisant, par exemple, le thème racine Theme.AppCompat.Light . Même si vous souhaitez une Toolbar personnalisée dans votre présentation, par exemple. Si vous implémentez le modèle de tiroir de navigation Over-Barre-under-Status Bar de la conception de matériaux, vous pouvez toujours appeler setSupportActionBar(toolbar) sans toujours transmettre la barre d'outils à ActionBarDrawerToggle(), laissant ainsi l'activité gérer l'icône de navigation.

Mais si vous voulez vraiment lier votre ActionBarDrawerToggle à une Toolbar qui n'est pas la barre d'action de l'activité, et qui a peut-être un style différent, une icône différente ou autre chose, il reste encore beaucoup à faire.

Le fait est que, lorsque vous ne transmettez pas la barre d'outils en tant que quatrième paramètre, l'activité est supposée fournir l'icône de navigation (la flèche) - et AppCompatActivity renvoie la valeur de l'attribut homeAsUpIndicator - elle est définie dans l'un ou l'autre des standards AppCompat. thèmes.

Cependant, lorsque vous passez explicitement la Toolbar, ActionBarDrawerToggle s'attend à ce que l'instance de barre d'outils fournisse l'indicateur de navigation dessiné - ce n'est pas le cas, car même si vous lui appliquez le style approprié, procédez comme suit:

<Android.support.v7.widget.Toolbar
        ...
        app:theme="?actionBarTheme"
        style="@style/Widget.AppCompat.Toolbar">

pour une raison quelconque (peut-être même un bogue), le style Widget.AppCompat.Toolbar n'a pas d'attribut navigationIcon, donc Toolbar renvoie null lorsque ActionBarDrawerToggle lui demande l'icône de navigation. Donc, pour faire face à cela, vous dérivez simplement du style et ajoutez l'attribut:

<Android.support.v7.widget.Toolbar
        ...
        app:theme="?actionBarTheme"
        style="@style/MyWidget.Toolbar">
<!-- styles.xml -->
<style name="MyWidget.Toolbar" parent="Widget.AppCompat.Toolbar">
    <item name="navigationIcon">?homeAsUpIndicator</item>
</style>

Vous pouvez maintenant utiliser le constructeur ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, 0, 0) tenant compte de la barre d’outils tout en maintenant l’icône de navigation en place.

2
Ivan Bartsov

Je l'ai réalisé en utilisant la disposition suivante: J'ai utilisé ActionBarDrawerToggle v7 Drawer.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    tools:context="com.example.toolbar.Drawer" >

    <include
        Android:id="@+id/tool1"
        layout="@layout/toolbar" />



    <Android.support.v4.widget.DrawerLayout
        Android:id="@+id/drawerLayout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_below="@id/tool1" >

        <FrameLayout
            Android:id="@+id/mainContent"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent" >
        </FrameLayout>

        <!-- Nav drawer -->

        <ListView
            Android:id="@+id/drawerList"
            Android:layout_width="240dp"
            Android:layout_height="match_parent"
            Android:layout_gravity="left"
            Android:background="@Android:color/white"
            Android:divider="@Android:color/white"
            Android:dividerHeight="8dp"
            Android:drawSelectorOnTop="true"
            Android:headerDividersEnabled="true" />
    </Android.support.v4.widget.DrawerLayout>

</RelativeLayout>

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.Toolbar xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app1="http://schemas.Android.com/apk/res/com.example.toolbar"
    Android:id="@+id/my_awesome_toolbar"
    Android:layout_width="fill_parent"
    Android:layout_height="75dp"
    Android:layout_alignParentLeft="true"
    Android:layout_alignParentTop="true"
    Android:background="?attr/colorPrimary"
    Android:minHeight="?attr/actionBarSize"
    app1:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app1:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >

</Android.support.v7.widget.Toolbar>

Drawer.Java

package com.example.toolbar;

import Android.content.res.Configuration;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v4.app.FragmentManager;
import Android.support.v4.widget.DrawerLayout;
import Android.support.v7.app.ActionBarActivity;
import Android.support.v7.app.ActionBarDrawerToggle;
import Android.support.v7.widget.Toolbar;
import Android.view.Gravity;
import Android.view.Menu;
import Android.view.MenuItem;
import Android.view.View;
import Android.widget.AdapterView;
import Android.widget.AdapterView.OnItemClickListener;
import Android.widget.ArrayAdapter;
import Android.widget.ListView;

public class Drawer extends ActionBarActivity {

    ActionBarDrawerToggle mDrawerToggle;
    private String[] days;
    ArrayAdapter<String> adapter;
    private ListView mDrawerList;
    DrawerLayout mDrawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drawer);

        days = new String[] { "sunday", "monday", "tuesday", "wednesday",
                "thursday", "friday", "saturday" };
        adapter = new ArrayAdapter<String>(this,
                Android.R.layout.simple_list_item_1, days);
        mDrawerList = (ListView) findViewById(R.id.drawerList);
        mDrawerList.setAdapter(adapter);
        mDrawerList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // TODO Auto-generated method stub

                Fragment fragment = new MyFragment();
                Bundle args = new Bundle();
                args.putString(MyFragment.ARG_PLANET_NUMBER, days[position]);
                // args.putInt(MyFragment.ARG_PLANET_NUMBER, position);
                fragment.setArguments(args);

                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction()
                        .replace(R.id.mainContent, fragment).commit();

            }

        });

        Toolbar toolbar = (Toolbar) findViewById(R.id.tool1);

        setSupportActionBar(toolbar);
        toolbar.setTitle("ToolBar Demo");
        toolbar.setLogo(R.drawable.ic_launcher);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar,
                R.string.open_navigation_drawer,
                R.string.close_navigation_drawer) {

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                // TODO Auto-generated method stub
                super.onDrawerSlide(drawerView, slideOffset);
            }

            /** Called when a drawer has settled in a completely closed state. */
            @Override
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getSupportActionBar().setTitle("hello");
            }

            /** Called when a drawer has settled in a completely open state. */
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getSupportActionBar().setTitle("hi");
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // getSupportActionBar().setDisplayHomeAsUpEnabled(true); //<---- added
        // getSupportActionBar().setHomeButtonEnabled(true); //<---- added

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) { // <---- added
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) { // <---- added
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState(); // important statetment for drawer to
                                    // identify
                                    // its state
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) { // <---- added
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onBackPressed() {
        if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) { // <----
                                                                        // added
            mDrawerLayout.closeDrawers();
            return;
        }
        super.onBackPressed();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
2
kunal.c

cette ligne s'assure que l'icône de hamburger est changée en flèche en cliquant. Assurez-vous que cela est écrit dans votre code.

mDrawerLayout.setDrawerListener(mDrawerToggle);
1
isudansh