【问题标题】:Change positions of menu items and hamburger button for a right-side drawer更改右侧抽屉的菜单项和汉堡按钮的位置
【发布时间】:2017-11-04 19:42:19
【问题描述】:

在我的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 类来自this answer

【问题讨论】:

    标签: android menu menuitem drawerlayout


    【解决方案1】:

    Toolbar 中的菜单将始终固定到最后,除了以某种方式直接修改 Toolbar 的行为之外,没有什么可以做的,这不是微不足道的。

    一种选择是完全放弃菜单,并将您自己的Button 添加到Toolbar 进行设置。不过,这可能有点笨拙,因为EndDrawerToggleButton 是动态创建和添加的,因此您想要在最后堆叠之前的任何其他Views 都必须创建和添加类似地,或者在设置切换后玩弄。

    但是,通过一些修改,我们可以让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) {}
    }
    

    初始化基本相同;按照惯例实例化,并在DrawerLayout 上添加为DrawerListener

    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(),因为drawable会在上面的方法中正确同步。


    请注意,此示例只是将MenuItem 添加到现有Menu,并将该项目设置为SHOW_AS_ACTION_ALWAYS。这将在给定菜单上按需要工作,但如果这与任何具有溢出项的菜单一起使用,三点溢出图标将出现在切换按钮之后。

    在这种情况下,如果您仍然希望在最后切换,则必须“手动”处理溢出;例如,通过为三点图标添加自定义项,并在弹出窗口中打开单独的菜单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多