89

首先,我知道这个问题之前出现过,但是在尝试了很多之后我仍然没有成功。我正在研究来自 Android 开发者网站的示例。

我正在尝试将菜单设置为从右到左打开,而不是在示例中如何实现(从左到右)。另外我想将打开菜单按钮移动到操作栏的右侧。我也在这里红色了一些答案,例如在这个答案中。

我尝试更改视图和布局的重力,但出现错误:

没有找到绝对重力的抽屉视图 LEFT

你能帮我弄清楚我的代码中的问题是什么,为了设置从右侧打开的菜单并将操作栏按钮移动到右侧,我应该改变什么?

xml代码在这里:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_gravity="right"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layoutDirection="rtl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ListView android:id="@+id/left_drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="10dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>
4

13 回答 13

156

在您的主布局中,将ListView重力设置为正确:

android:layout_gravity="right" 

同样在您的代码中:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, R.string.drawer_open,
            R.string.drawer_close) {

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
                mDrawerLayout.closeDrawer(Gravity.RIGHT);
            } 
            else {
                mDrawerLayout.openDrawer(Gravity.RIGHT);
            }
        }
        return false;
    }
};

希望它有效:)

于 2013-10-14T10:21:50.997 回答
64

将此代码添加到清单:

<application android:supportsRtl="true">

然后在 Oncreate 上写下这段代码:

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

这个对我有用。;)

于 2014-10-08T17:36:26.797 回答
40

解决方案


your_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="end">

    <include layout="@layout/app_bar_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:itemTextColor="@color/black"
        app:menu="@menu/activity_root_drawer" />

</android.support.v4.widget.DrawerLayout>

你的活动.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT)) {
                drawer.closeDrawer(Gravity.RIGHT);
            } else {
                drawer.openDrawer(Gravity.RIGHT);
            }
        }
    });
//...
}
于 2015-12-17T08:21:29.863 回答
4

这个答案对于将导航设置为从右到左打开很有用,但它没有解决方案将其图标设置为右侧。这段代码可以修复它。如果将其drawer作为第一个参数和ViewCompat.LAYOUT_DIRECTION_RTL第二个参数,则整个布局将设置为 RTL。这是一个快速简单的解决方案,但对于只想将菜单设置为从右到左打开并将其图标设置在右侧的人,我认为这不是一个正确的解决方案。(尽管这取决于您的目的。)但是,我建议使用 .toolbar而不是drawer. 这样一来,工具栏就变成了RTL。所以我认为这两个答案的组合完全可以做你想要的。

根据这些描述,您的代码应该是这样的:

(将这些行添加到 onCreate 方法)

final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); // Set it final to fix the error that will be mention below.

    ViewCompat.setLayoutDirection(toolbar, ViewCompat.LAYOUT_DIRECTION_RTL);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT))
                drawer.closeDrawer(Gravity.RIGHT);
            else
                drawer.openDrawer(Gravity.RIGHT);
        }
    });

请注意,您应该将抽屉设为最终状态,否则您将收到此错误:

从内部类中访问变量'drawer',需要声明为final

并且不要忘记使用end而不是startinonNavigationItemSelected方法:

drawer.closeDrawer(GravityCompat.END);

在你的 activity_main.xml

<android.support.v4.widget.DrawerLayout 
   android:id="@+id/drawer_layout"
   tools:openDrawer="end">

   <android.support.design.widget.NavigationView
      android:id="@+id/nav_view"
      android:layout_gravity="end"/>
</android.support.v4.widget.DrawerLayout>
于 2018-06-11T14:03:48.253 回答
3

看看这个:在 DrawerLayout form 从右到左滑动 ExpandableListView

我假设你已经实现了 ActionBarDrawerToggle,诀窍是onOptionsItemSelected(MenuItem item)用这个覆盖 ActionBarDrawerToggle 对象内的方法:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawer.isDrawerOpen(Gravity.RIGHT)) {
                mDrawer.closeDrawer(Gravity.RIGHT);
            } else {
                mDrawer.openDrawer(Gravity.RIGHT);
            }
            return true;
        }
        return false;
    }

确保并onOptionsItemSelected(MenuItem item)在 Activity 中调用它:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

if(mDrawerToggle.onOptionsItemSelected(item)) {
    return true;
}

return super.onOptionsItemSelected(item);
}

这将允许您使用主页按钮功能。要将按钮移动到操作栏的右侧,您必须实现一个自定义操作项,也许还有一些其他的东西可以让它像您想要的那样工作。

于 2013-09-13T13:23:58.703 回答
3

这是抽屉上的文档,您似乎可以将其配置为从左侧或右侧拉出。

抽屉定位和布局是使用子视图上的 android:layout_gravity 属性控制的,对应于您希望抽屉从视图的哪一侧出现:左侧或右侧。(或在支持布局方向的平台版本上开始/结束。)

http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html

于 2013-08-31T11:37:25.110 回答
3

以下错误的主要问题:

没有找到绝对重力的抽屉视图 LEFT

是,你定义了

android:layout_gravity="right"

对于右侧的列表视图,但尝试通过调用此函数从左侧打开抽屉:

mDrawerToggle.syncState();

并点击汉堡图标!

只需评论上述功能并尝试像@Rudi 所说的那样处理菜单的打开/关闭!

于 2016-02-11T04:47:38.397 回答
3

我通过改变导航视图的重力解决了这个问题

机器人:layout_gravity

结束不是开始

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/activity_drawer" />

它对我有用。

于 2017-01-01T13:40:08.710 回答
2

我对 Android Studio 中的 Navigation Drawer Activity 示例进行了以下修改。使用支持库 25.3.1。

MainActivity.java:

private DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

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

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
        mDrawerLayout.closeDrawer(GravityCompat.END);
    } else {
        super.onBackPressed();
    }
}

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    switch (itemId) {
        case android.R.id.home:
            finish();
            return true;

        case R.id.action_right_drawer:
            if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                mDrawerLayout.closeDrawer(GravityCompat.END);
            } else {
                mDrawerLayout.openDrawer(GravityCompat.END);
            }
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    mDrawerLayout.closeDrawer(GravityCompat.END);
    return true;
}

main.xml(从https://material.io/icons/下载 ic_menu_white_24px ):

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_right_drawer"
        android:title="Drawer menu"
        android:icon="@drawable/ic_menu_white_24px"
        android:orderInCategory="100"
        app:showAsAction="always" />
</menu>

在 activity_main.xml 更改

android:layout_gravity="start"

android:layout_gravity="end"
于 2017-04-03T06:01:14.693 回答
2

从 rtl 打开它不利于用户体验,为了使其响应用户区域设置,我刚刚在 DrawerLayout 参数中添加了以下行:

android:layoutDirection="locale"

将它添加到我的 AppBarLayout 以使汉堡布局也匹配抽屉打开方向。

于 2017-08-25T16:01:35.030 回答
2

您应该首先将此代码放在应用程序标记中的 AppManifest.xml 中:

android:supportsRtl="true"

然后在您的 activity_main.xml 文件中,放入这段代码:

android:layout_direction="rtl"
于 2015-12-26T14:33:54.940 回答
1

DrawerLayout属性 android:layout_gravity="right|end"tools:openDrawer="end" NavigationView属性 android:layout_gravity="end"

XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:layout_gravity="right|end"
    tools:openDrawer="end">

    <include layout="@layout/content_main" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Java Code

// Appropriate Click Event or Menu Item Click Event

if (drawerLayout.isDrawerOpen(GravityCompat.END)) 
{
     drawerLayout.closeDrawer(GravityCompat.END);
} 
else 
{
     drawerLayout.openDrawer(GravityCompat.END);
}
//With Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //Gravity.END or Gravity.RIGHT
            if (drawer.isDrawerOpen(Gravity.END)) {
                drawer.closeDrawer(Gravity.END);
            } else {
                drawer.openDrawer(Gravity.END);
            }
        }
    });
//...
}
于 2020-03-29T12:34:38.980 回答
1

在 NavigationView 内的布局文件中设置此属性android:layout_gravity="end"并在 DrawerLayout 中设置tools:openDrawer="end"

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".tasks.TasksActivity"
    android:id="@+id/drawer_layout"
    tools:openDrawer="end">

<!-- Navigation Drawer -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer_actions" />

</androidx.drawerlayout.widget.DrawerLayout>

输出

在此处输入图像描述

于 2021-07-06T18:35:05.823 回答