问题
In my Toolbar
, I have a menu with one item "settings", and a DrawerLayout
with a hamburger icon aligned to the right.
Now it looks like this:
I want the hamburger to be on the right, like this:
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);
}
}
The EndDrawerToggle
class is from this answer.
回答1:
The menu in a Toolbar
will always be pinned to the end, and there's not much that can be done about that, apart from directly modifying Toolbar
's behavior somehow, which would not be trivial.
One option would be to forgo the menu altogether, and add your own Button
to the Toolbar
for the settings. This might be a little unwieldy, though, since EndDrawerToggle
's Button
is created and added dynamically, and so any other View
s you'd want stacked before it on the end would have to be either created and added similarly, or juggled around after the toggle has been set.
However, with some modifications, we can get EndDrawerToggle
to integrate directly with the menu, setting its toggle drawable as the icon on an always-shown menu item we add at the end. This actually ends up being a simpler class, since we don't need to provide an ImageButton
for the drawable, as we did when adding the toggle directly to the 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) {}
}
Initialization is basically the same; instantiate per usual, and add as a DrawerListener
on the DrawerLayout
.
drawerToggle = new EndMenuDrawerToggle(mDrawerLayout,
myToolbar,
R.string.open_drawer_end,
R.string.close_drawer_end);
mDrawerLayout.addDrawerListener(drawerToggle);
...
The difference comes in the onCreateOptionsMenu()
method, where we pass the menu we inflate there to the toggle's setToggleOnMenu()
method.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
drawerToggle.setToggleOnMenu(menu);
return true;
}
We do not call syncState()
with this class, as the drawable will be correctly synced in the method above.
Do note that this example simply adds a MenuItem
to the existing Menu
, and sets that item as SHOW_AS_ACTION_ALWAYS
. This will work as desired with the given menu, but if this is used with any menu that will have overflow items, the three-dot overflow icon is going to appear past the toggle.
In that case, if you still want the toggle at the very end, the overflow will have to be handled "manually"; e.g., by adding a custom item for the three-dot icon, and opening a separate menu in a popup.
来源:https://stackoverflow.com/questions/47114868/change-positions-of-menu-items-and-hamburger-button-for-a-right-side-drawer