90

First of all I know this question appeared here before but after trying a lot I still didn't succeed. I working on the example from Android Developers site.

I'm trying to set the menu to be opened from right to left instead of how its implementing in the example (from left to right). In addition I want to move the open menu button to the right side of the action bar. I also red some answers here, for example in this answer.

I try to change the gravity of the views and the layouts but I get the error:

no drawer view found with absolute gravity LEFT

Can you please help me to figure out what is the problem in my code and what should I change in order to set the menu to be opened from the right, and to move the action bar button to the right side?

the xml code is here:

<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>
MMG
  • 3,226
  • 5
  • 16
  • 43
galvan
  • 7,400
  • 7
  • 38
  • 55
  • possible duplicate of [slide ExpandableListView at DrawerLayout form right to left](http://stackoverflow.com/questions/17792237/slide-expandablelistview-at-drawerlayout-form-right-to-left) – d370urn3ur Sep 13 '13 at 13:13
  • Take a look at https://github.com/Ali-Rezaei/SlidingDrawer which makes it possible to slide from any side by few lines of code. – Ali Jun 13 '15 at 19:45
  • Please see answer https://stackoverflow.com/a/44076363/5332645 – Aman Saxena Jun 25 '18 at 08:46
  • Check out [this answer](https://stackoverflow.com/a/67787575/10239462) if you are using the navigation components. – mohsen zandie Jun 01 '21 at 11:01

15 Answers15

157

In your main layout set your ListView gravity to right:

android:layout_gravity="right" 

Also in your code :

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;
    }
};

hope it works :)

sfmirtalebi
  • 370
  • 7
  • 16
Rudi
  • 4,304
  • 4
  • 34
  • 44
  • 2
    @Rudi: Do you know the answer of second part? I mean how to make actionbar right to left. (Drawer and up navigation icon direction also change) – Alireza Farahani Dec 04 '14 at 08:45
  • @alireza why dont you use a customised actionbar ? – Rudi Dec 04 '14 at 10:17
  • @Rudi: You mean `setCustomView` method? If yes, would you mind pasting some links showing how to do that? – Alireza Farahani Dec 04 '14 at 11:01
  • @alireza I meant, instead of using actionbar in the top of your view, make your custom Actionbar in your main xml and set it up as u wish. – Rudi Dec 06 '14 at 09:38
  • @Rudi: But then, how can I achieve the same behavior like up navigation and drawer open and close animation? Do I have to implement them from scratch? – Alireza Farahani Dec 06 '14 at 10:05
  • @Raudi. Thanks for your answer.. i have followed your code and it doesnot give any errors but even after that it dosent shows anything in my action bar.. nothing at all – Abstract Dec 11 '14 at 06:34
  • @Abstract I know this is older stuff, but in case somebody stumbles upon this (instead of a full answer on here somewhere), the answer is two steps. Step 1: create the folder res/menu and within that actionbar1.xml. This should contain a menu tag and within that tag some item tags. Step 2: in your activity, override `onCreateOptionsMenu(Menu menu)` and make it do `getMenuInflater().inflate(R.menu.actionbar1,menu); return true;` – lucidbrot Mar 01 '16 at 21:36
  • This is not the accepted solution, its now deprecated – EngineSense Apr 25 '16 at 09:13
  • To achieve hamburger icon to the right side, create a drawer_menu.xml file in res/menu folder with a hamburger icon in it. Then on its click, call the mDrawerToggle.onOptionsItemSelected(MenuItem item). Remember to update the click id inside the above method with your menu item id instead of android.R.id.home. This will bind the menu item with the right aligned navigation drawer. – Sonu Sanjeev Oct 26 '18 at 05:20
66

Add this code to manifest:

<application android:supportsRtl="true">

and then write this code on Oncreate:

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

It works for me. ;)

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
Amir Bax
  • 721
  • 5
  • 2
  • 1
    this is correct answer , just set gravity of your listview to start , then use this code , everything should be fine – Mahdi Giveie Dec 21 '14 at 10:57
  • 9
    It's working , however , setLayoutDirection(View.LAYOUT_DIRECTION_RTL) is for API above 17 , so you cannot use this for api lower – Milad Mar 12 '15 at 10:45
  • 6
    Won't this flip the whole layout of the activity, even the toStartOf/toEndOf, etc...? – TWiStErRob Mar 14 '15 at 17:04
  • 15
    This is wrong answer. It flips entire layout of activity from right to left. – Tarun Deep Attri Feb 02 '16 at 10:28
  • 1
    Thought it's a quick solution but not a correct one. – sidhanshu Mar 20 '17 at 12:18
  • Thanks a lot. After looking too many solutions and finding too many complex answers this answer is quickest and simplest. This is what I was looking for as when I want to do drawer from Right to left I actually want the whole layout go from right to left. Language of Application is RTL so this best suits. – Abdul Rehman Oct 28 '17 at 13:49
40

SOLUTION


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);
            }
        }
    });
//...
}
Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63
  • 2
    Works great. But the toolbar icon still appears on left. How to bring toggle button icon to right as well? – Darush Apr 05 '18 at 13:40
  • 1
    i gave android:layout_gravity="end" for both Drawerlayout and NavigationView as well, its working fine. – varotariya vajsi Apr 09 '18 at 09:53
  • `toolbar.setNavigationOnClickListener` requires min Api Level 21 :( – SepJaPro2.4 Jun 11 '18 at 10:22
  • @SepJaPro2.4 yes, but `From August 2018, new apps must target at least Android 8.0 (API level 26). From November 2018, app updates must target Android 8.0 (API level 26).` (Google) – Volodymyr Kulyk Jun 11 '18 at 10:46
  • tell that to my product manager :)) he insists on the min API 17 and material design :)) and I can not argue ... thank you for the response by the way – SepJaPro2.4 Jun 11 '18 at 11:33
  • 2
    Add android:layoutDirection="rtl" in your AppBarLayout XML to set the toggle button to the right – Terranology Jun 26 '18 at 19:51
5

This answer is useful to set the navigation be open from right to left, but it has no solution to set its icon to be right side. This code can fix it. If you give it the drawer as its first param and ViewCompat.LAYOUT_DIRECTION_RTL as its second param, the entier layout will be set to RTL. It is a quick and simple solution, but I don't think it can be a correct solution for who that want to only set the menu to be opened from right to left and set its icon to be on right side. (Although, it's depended to your purpose.) However, I suggest giving the toolbar instead of the drawer. In this way just the toolbar has become RTL. So I think the combination of these 2 answers can exactly do what you want.

According to these descriptions, your code should be like this:

(Add these lines to onCreate method)

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);
        }
    });

Notice that you should make drawer final, otherwise you will get this error:

Variable 'drawer' is accessed from within inner class, needs to be declared final

And don't forget to use end instead of start in onNavigationItemSelected method:

drawer.closeDrawer(GravityCompat.END);

and in your 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>
3

Here is the documentation on the drawer and it appears that you can configure it to pull out from the left or right.

Drawer positioning and layout is controlled using the android:layout_gravity attribute on child views corresponding to which side of the view you want the drawer to emerge from: left or right. (Or start/end on platform versions that support layout direction.)

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

KickAss
  • 4,210
  • 8
  • 33
  • 41
  • I saw this answer before, and I also mentioned it in my question. – galvan Aug 31 '13 at 11:49
  • Okay. Try using `end` instead of `right` in the gravity. EDIT: Remove `android:layout_gravity="right"` from the `android.support...DrawerLayout` and change `android:layout_gravity="right"` to `android:layout_gravity="end"` inside `ListView` – KickAss Aug 31 '13 at 11:53
  • 1
    i still got the error: no drawer view found with absolute gravity LEFT. I added to the manifest android:supportsRtl="true", and in the xml under the drawerLayout I added android:layoutDirection="rtl", and then the menu opens on the right, but now it doesn't close when i ckick the menu button (in the action bar) when i click on any item in the list, or on outside from the list it closes but no when i ckick on the menu button in the action bar, any ideas why? – galvan Aug 31 '13 at 12:04
  • I'm not entirely sure, but... as the direction and position of the Drawer is now changed, in your Activity, as per the Android example, you should have the Toggle switch method/button listener, check if that needs to be modified so that it knows to close by moving it RightToLeft. It might be thinking hold on menu is already to the Left (i.e. hidden) so it wont close (if that makes sense)... – KickAss Aug 31 '13 at 12:07
  • Guys, i am also doing same kind of thing but if use laoutDirection="rtl" then i have to change minSdk as 17 but my app need to support API level 10. can you guys help me so that my app can support API 10. – Kapil Nov 04 '13 at 19:06
  • Check this out buddy: http://android-developers.blogspot.co.uk/2013/03/native-rtl-support-in-android-42.html – KickAss Nov 04 '13 at 19:20
3

Take a look at this: slide ExpandableListView at DrawerLayout form right to left

I assume you have the ActionBarDrawerToggle implemented, the trick is to override the onOptionsItemSelected(MenuItem item) method inside the ActionBarDrawerToggle object with this:

    @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;
    }

make sure and call this from onOptionsItemSelected(MenuItem item) in the Activity:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

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

return super.onOptionsItemSelected(item);
}

This will allow you to use the the home button functionality. To move the button to the right side of the action bar you will have to implement a custom action item, and maybe some other stuff to get it to work like you want.

Community
  • 1
  • 1
d370urn3ur
  • 1,736
  • 4
  • 17
  • 24
3

the main issue with the following error:

no drawer view found with absolute gravity LEFT

is that, you defined the

android:layout_gravity="right"

for list-view in right, but try to open the drawer from left, by calling this function:

mDrawerToggle.syncState();

and clicking on hamburger icon!

just comment the above function and try to handle open/close of menu like @Rudi said!

Parissa Kalaee
  • 606
  • 1
  • 9
  • 17
3

I have solved this problem by changing the gravity of the navigationview

android:layout_gravity

to end instead of start

<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" />

It worked for me.

MobileEvangelist
  • 2,583
  • 1
  • 25
  • 36
2

You should firstly put this code in your AppManifest.xml in the application tag:

android:supportsRtl="true"

then in your activity_main.xml file, put this piece of code:

android:layout_direction="rtl"
Hussein El Feky
  • 6,627
  • 5
  • 44
  • 57
2

I did following modification to the Navigation Drawer Activity example in Android Studio. With support libraries 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 (download ic_menu_white_24px from https://material.io/icons/):

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

In activity_main.xml change

android:layout_gravity="start"

to

android:layout_gravity="end"
2

Making it open from rtl isn't good for user experience, to make it responsive to the user locale I just added the following line to my DrawerLayout parameters:

android:layoutDirection="locale"

Added it to my AppBarLayout to make the hamburger layout match the drawer opening direction too.

arbel03
  • 1,217
  • 2
  • 14
  • 24
2

DrawerLayout Properties android:layout_gravity="right|end" and tools:openDrawer="end" NavigationView Property 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);
            }
        }
    });
//...
}
Ashvin solanki
  • 4,802
  • 3
  • 25
  • 65
1

In your layout file inside NavigationView set this attribute android:layout_gravity="end" and set tools:openDrawer="end" in the 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>

Output

enter image description here

Divyanshu Kumar
  • 1,272
  • 15
  • 15
1

I know this is an old question, but I've been struggling with this problem for a few days now and finally achived the solution. If you want to use the default new project "Navigation Drawer Activity" to work with a drawer from right to left:

  1. Create a custom DrawerLayout class:
public class CustomDrawerLayout extends DrawerLayout {

    public CustomDrawerLayout(@NonNull Context context) {
        super(context);
    }

    public CustomDrawerLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomDrawerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void open() {
        openDrawer(GravityCompat.END);
    }

    @Override
    public void close() {
        closeDrawer(GravityCompat.END);
    }

    @Override
    public boolean isOpen() {
        return isDrawerOpen(GravityCompat.END);
    }

}
  1. On activity_main.xml:
    • set DrawerLayout tools:openDrawer="end"
    • set NavigationView android:layout_gravity="end"
    • change tag view from androidx.drawerlayout.widget.DrawerLayout to your CustomDrawerLayout com.example.CustomDrawerLayout

If you create new menu options, it is important that the id of the item in menu/activity_main_drawer.xml is the same as the id of the fragment in navigation/mobile_navigation.xml.

Sanket Shah
  • 4,352
  • 3
  • 21
  • 41
0

Summarising multiple answers into one which worked for me.

Following were my requirements

1. Align navigation drawer hamburger icon to write

2. Start the navigation drawer from right to left

3. Achieve the above two points without changing the direction to rtl of the whole layout


To start the Navigation drawer from right to left

Set DrawerLayout tools:openDrawer="end"

Set NavigationView android:layout_gravity="end"

mDrawerToggle.setToolbarNavigationClickListener {
        if (binding.drawerLayout.isDrawerOpen(GravityCompat.END)) {
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        } else {
            binding.drawerLayout.openDrawer(GravityCompat.END)
        }
    }

To set the Hamburger menu to the right

Set AppBarLayout android:layoutDirection="rtl"

Chetan Gaikwad
  • 1,268
  • 1
  • 13
  • 26