如何设置导航抽屉从右到左打开

时间:2013-08-31 10:44:29

标签: android navigation-drawer right-to-left

首先我知道这个问题出现在此之前,但在尝试了很多之后我仍然没有成功。 我正在研究这个例子 Android Developers site

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

我尝试改变视图和布局的重力,但我收到错误:

找不到具有绝对重力的抽屉视图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>

13 个答案:

答案 0 :(得分:148)

在您的主要布局中,将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;
    }
};

希望它有效:)

答案 1 :(得分:56)

将此代码添加到清单:

<application android:supportsRtl="true">

然后在Oncreate上编写此代码:

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

它对我有用。 ;)

答案 2 :(得分:33)

<强>解

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>

YourActivity.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);
            }
        }
    });
//...
}

答案 3 :(得分:2)

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

  

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

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

答案 4 :(得分:2)

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

android:supportsRtl="true"

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

android:layout_direction="rtl"

答案 5 :(得分:2)

以下错误的主要问题:

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

就是这样,你定义了

android:layout_gravity="right"

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

mDrawerToggle.syncState();

点击汉堡包图标!

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

答案 6 :(得分:2)

我通过将导航视图的重力更改为 end 而不是 start 解决了这个问题 它适用于我

答案 7 :(得分:2)

This answer对于将导航从右向左设置为有用非常有用,但它没有将其图标设置为右侧的解决方案。 This code可以修复它。如果您将ModuleA作为其第一个参数并将drawer作为其第二个参数,则将其设置为RTL。这是一个快速而简单的解决方案,但我不认为对于那些只想将菜单从右到左设置并将其图标设置在右侧的人来说,它可以是一个正确的解决方案。 (虽然,它取决于您的目的。)但是,我建议您使用ViewCompat.LAYOUT_DIRECTION_RTL而不是toolbar。通过这种方式,只有工具栏已成为RTL。所以我认为这两个答案的组合可以完全按照你想要的那样做。

根据这些描述,您的代码应如下所示:

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

drawer

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

  

可变抽屉&#39;从内部类中访问,需要   宣布最终

并且不要忘记在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); } }); 方法中使用end代替start

onNavigationItemSelected

并在您的activity_main.xml

drawer.closeDrawer(GravityCompat.END);

答案 8 :(得分:1)

看看这个:slide ExpandableListView at DrawerLayout form right to left

我假设您已经实现了ActionBarDrawerToggle,其技巧是使用以下方法覆盖ActionBarDrawerToggle对象中的onOptionsItemSelected(MenuItem item)方法:

    @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)调用此内容:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

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

return super.onOptionsItemSelected(item);
}

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

答案 9 :(得分:1)

我对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"

答案 10 :(得分:1)

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

android:layoutDirection="locale"

将它添加到我的AppBarLayout中,使汉堡包布局也与抽屉打开方向相匹配。

答案 11 :(得分: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);
            }
        }
    });
//...
}

答案 12 :(得分:0)

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

<?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>

输出

enter image description here