Изменить положение пунктов меню и кнопки гамбургера для правого ящика

В моем Toolbar у меня есть меню с одним пунктом «Настройки» и DrawerLayout со значком гамбургера, выровненным по правому краю.

Теперь это выглядит так:

введите здесь описание изображения

Я хочу, чтобы гамбургер был справа, вот так:

введите здесь описание изображения

menu.xml:

<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings_black_48dp"
        app:showAsAction="always" />
</menu>

MainActivity:

public class MainActivity extends AppCompatActivity {
    private DrawerLayout mDrawerLayout;
    //EndDrawerToggle is class for setup DrawerLayout with an end-aligned drawer
    private EndDrawerToggle drawerToggle;   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context=this;
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        myToolbar.setTitle("");
        setSupportActionBar(myToolbar);
        drawerToggle = new EndDrawerToggle(this,
                mDrawerLayout,
                myToolbar,
                R.string.drawer_open,
                R.string.drawer_close);
        mDrawerLayout.addDrawerListener(drawerToggle);    
        //....
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.settings) {
            //do smth
        }
        return super.onOptionsItemSelected(item);
    }

}

Класс EndDrawerToggle взят из этот ответ.


person Olga    schedule 04.11.2017    source источник


Ответы (1)


Меню в Toolbar всегда будет закреплено до конца, и с этим мало что можно сделать, кроме как напрямую изменить поведение Toolbar, что было бы нетривиально.

Одним из вариантов было бы вообще отказаться от меню и добавить свои собственные Button к Toolbar для настроек. Однако это может быть немного громоздким, поскольку Button EndDrawerToggle создается и добавляется динамически, и поэтому любые другие View, которые вы хотите разместить перед ним в конце, должны быть либо созданы и добавлены аналогичным образом, либо жонглировать после того, как переключатель был был установлен.

Тем не менее, с некоторыми изменениями, мы можем заставить EndDrawerToggle интегрироваться непосредственно с меню, настроив его переключатель в качестве значка на постоянно отображаемом пункте меню, который мы добавляем в конце. На самом деле это более простой класс, поскольку нам не нужно предоставлять ImageButton для рисования, как мы делали при добавлении переключателя непосредственно в Toolbar.

import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;


public class EndMenuDrawerToggle implements DrawerLayout.DrawerListener {

    private final DrawerLayout drawerLayout;
    private final Toolbar toolbar;
    private final DrawerArrowDrawable arrowDrawable;
    private final int openDrawerContentDesc, closeDrawerContentDesc;
    private MenuItem toggleItem;

    public EndMenuDrawerToggle(DrawerLayout drawerLayout, Toolbar toolbar,
                               int openDrawerContentDesc, int closeDrawerContentDesc) {
        this.drawerLayout = drawerLayout;
        this.toolbar = toolbar;

        this.openDrawerContentDesc = openDrawerContentDesc;
        this.closeDrawerContentDesc = closeDrawerContentDesc;

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

    public void setToggleOnMenu(Menu menu) {
        toggleItem = menu.add(openDrawerContentDesc);
        toggleItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        toggleItem.setIcon(arrowDrawable);
        toggleItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    toggle();
                    return true;
                }
            }
        );

        setPosition(drawerLayout.isDrawerOpen(GravityCompat.END) ? 1f : 0f);
    }

    private void toggle() {
        final int drawerLockMode = drawerLayout.getDrawerLockMode(GravityCompat.END);
        if (drawerLayout.isDrawerVisible(GravityCompat.END)
            && (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) {
            drawerLayout.closeDrawer(GravityCompat.END);
        }
        else if (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_CLOSED) {
            drawerLayout.openDrawer(GravityCompat.END);
        }
    }

    private void setPosition(float position) {
        if (position == 1f) {
            arrowDrawable.setVerticalMirror(true);
            toggleItem.setTitle(closeDrawerContentDesc);
        }
        else if (position == 0f) {
            arrowDrawable.setVerticalMirror(false);
            toggleItem.setTitle(openDrawerContentDesc);
        }
        arrowDrawable.setProgress(position);
    }

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

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

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

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

Инициализация в основном такая же; создайте экземпляр как обычно и добавьте DrawerListener к DrawerLayout.

drawerToggle = new EndMenuDrawerToggle(mDrawerLayout,
                                       myToolbar,
                                       R.string.open_drawer_end,
                                       R.string.close_drawer_end);
mDrawerLayout.addDrawerListener(drawerToggle);
...

Разница заключается в методе onCreateOptionsMenu(), где мы передаем меню, которое мы там раздуваем, методу setToggleOnMenu() переключателя.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);

    drawerToggle.setToggleOnMenu(menu);

    return true;
}

Мы не вызываем syncState() с этим классом, так как рисуемый объект будет правильно синхронизирован в методе выше.

скриншот


Обратите внимание, что в этом примере просто добавляется MenuItem к существующему Menu и устанавливается этот элемент как SHOW_AS_ACTION_ALWAYS. Это будет работать по желанию с данным меню, но если это используется с любым меню, которое будет иметь элементы переполнения, значок переполнения с тремя точками появится за переключателем.

В этом случае, если вы все еще хотите, чтобы переключатель был в самом конце, переполнение должно быть обработано «вручную»; например, добавив пользовательский элемент для трехточечного значка и открыв отдельное меню во всплывающем окне.

person Mike M.    schedule 06.11.2017