Android navigation drawer toggle icon to right

六眼飞鱼酱① 提交于 2019-11-26 14:34:59

I wrote the EndDrawerToggle class for a setup very similar to yours - a DrawerLayout with an end-aligned drawer View, in an AppCompatActivity with a custom Toolbar as the support ActionBar.

import android.app.Activity;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import android.support.v7.widget.AppCompatImageButton;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.Toolbar.LayoutParams;
import android.view.View;
import android.view.View.OnClickListener;


public class EndDrawerToggle implements DrawerLayout.DrawerListener {

    private DrawerLayout drawerLayout;
    private DrawerArrowDrawable arrowDrawable;
    private AppCompatImageButton toggleButton;
    private String openDrawerContentDesc;
    private String closeDrawerContentDesc;

    public EndDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar,
                           int openDrawerContentDescRes, int closeDrawerContentDescRes) {

        this.drawerLayout = drawerLayout;
        this.openDrawerContentDesc = activity.getString(openDrawerContentDescRes);
        this.closeDrawerContentDesc = activity.getString(closeDrawerContentDescRes);

        arrowDrawable = new DrawerArrowDrawable(toolbar.getContext());
        arrowDrawable.setDirection(DrawerArrowDrawable.ARROW_DIRECTION_END);

        toggleButton = new AppCompatImageButton(toolbar.getContext(), null,
                                                R.attr.toolbarNavigationButtonStyle);
        toolbar.addView(toggleButton, new LayoutParams(GravityCompat.END));
        toggleButton.setImageDrawable(arrowDrawable);
        toggleButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    toggle();
                }
            }
        );
    }

    public void syncState() {
        if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
            setPosition(1f);
        }
        else {
            setPosition(0f);
        }
    }

    public void toggle() {
        if (drawerLayout.isDrawerOpen(GravityCompat.END)) {
            drawerLayout.closeDrawer(GravityCompat.END);
        }
        else {
            drawerLayout.openDrawer(GravityCompat.END);
        }
    }

    public void setPosition(float position) {
        if (position == 1f) {
            arrowDrawable.setVerticalMirror(true);
            toggleButton.setContentDescription(closeDrawerContentDesc);
        }
        else if (position == 0f) {
            arrowDrawable.setVerticalMirror(false);
            toggleButton.setContentDescription(openDrawerContentDesc);
        }
        arrowDrawable.setProgress(position);
    }

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
        setPosition(Math.min(1f, Math.max(0, slideOffset)));
    }

    @Override
    public void onDrawerOpened(View drawerView) {
        setPosition(1f);
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        setPosition(0f);
    }

    @Override
    public void onDrawerStateChanged(int newState) {
    }
}

The EndDrawerToggle class is a complete replacement for ActionBarDrawerToggle in this case, so you will not need any of the setup that you currently have for that. All of the DrawerListener methods are still available for override, but it is not necessary to do so for the basic functionality, as EndDrawerToggle handles toggling the drawer state on its own. It is similarly unnecessary to handle the toggle click yourself, so you do not need the navigation OnClickListener either.

Simply instantiate the toggle, add it as a DrawerListener, and sync it. I would recommend syncing the toggle in the onPostCreate() method, to ensure that it syncs correctly, for example, after an orientation change.

private EndDrawerToggle drawerToggle;
...

public void initNavigationDrawer() {
    NavigationView navigationView = ...
    ...

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

    drawerToggle = new EndDrawerToggle(this,
                                       drawerLayout,
                                       toolbar,
                                       R.string.drawer_open,
                                       R.string.drawer_close);

    drawerLayout.addDrawerListener(drawerToggle);
}

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

In your android manifest add this line:

android:supportsRtl="true"

to your application, like so:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"

Then in your onCreate method, add this line:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

WARNING::: This only works for SdkVersion 17+, so if your application targets a lower minimum SDK, you will have to create a custom menu and override the OnCreateOptions method(Unless there's another way which I'm not aware of, which is definitely possible).

https://developer.android.com/guide/topics/manifest/application-element.html#supportsrtl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!