How to use NavigationView - android

I have an activity which has a navigationView and a toolbar (I set toolbar name manually).
My problem is; when I open the navigationView, it goes out of activity and back to previous activity.
I tried many ways to find the problem and I found when i wasn't using this line the problem has been solved and navigation menu opens without any problem.
setSupportActionBar(toolbar);
I don't know which one the problem is? toolbar or navigation?
Note : There is nothing special about the styles.
Activity :
Toolbar toolbar = findViewById (R.id.toolbar_StudentList);
setSupportActionBar(toolbar);//Set actionBar with toolbar
if(getSupportActionBar() != null)
{
getSupportActionBar().setDisplayShowTitleEnabled(false);//Remove actionBar title
toolbar.setTitle(mClassEntry.getClassName());
}
DrawerLayout drawer = findViewById (R.id.drawerLayout_StudentList);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this , drawer , toolbar , 0b0, 0);
toggle.syncState();
NavigationView drawerItems = findViewById (R.id.navigationView_StudentList);
drawerItems.setNavigationItemSelectedListener(item -> {
.
.
.
}
Xml :
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.user.classmanager.StudentActivity"
android:id="#+id/drawerLayout_StudentList"
style="#style/DrawerLayout_all"
>
<FrameLayout
android:id="#+id/frameLayout_StudentList"
style="#style/Width_height_all_both_matchParent"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_StudentList"
style="#style/ToolBar_all"
/>
<RelativeLayout
style="#style/RelativeLayout_searchView_all"
>
<android.support.v7.widget.SearchView
android:id="#+id/searchView_StudentList"
style="#style/SearchView_all"
/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_StudentList"
style="#style/RecyclerView_FrameLayout_all"
/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigationView_StudentList"
style="#style/NavigationView_StudentList"
/>
</android.support.v4.widget.DrawerLayout>
Also my toolbar has a icon to close activity :
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toolbar_backicon, menu);//Back item in Toolbar
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item)
{
finish();//close activity
return super.onOptionsItemSelected(item);
}

in
public boolean onOptionsItemSelected(MenuItem item)
{
finish();//close activity
return super.onOptionsItemSelected(item);
}
you must specify the id of your close button so that the activity only closes when you click on the icon on the close button . In this you activity will close everytime , so must replace the code to something like this
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getId()==R.id.closeButton)
{ finish();//close activity
return true;
}
return super.onOptionsItemSelected(item);
}

Related

Android ToolBar Menu Item not Clickable

My android app menu item is not clickable I Add app:showAsAction="always" and android:enabled="true" to the menu item and The Item Button is shown but it's not clickable, What Im missing here ?
App Theme : parent="Theme.MaterialComponents.DayNight.DarkActionBar"
Layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:orientation="vertical"
tools:context=".Settings.ReportTable">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:id="#+id/toolbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/balance_table_SV"/>
</LinearLayout>
Activity :
public class ReportTable extends AppCompatActivity {
ScrollView balance_table_SV;
TableLayout tableLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_table);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.excel);
balance_table_SV = findViewById(R.id.balance_table_SV);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.excel, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.menu.excel) {
export_to_excel();
}
return super.onOptionsItemSelected(item);
}
}
First of all, it looks like you're comparing the item ID to the resource ID of the entire menu (R.menu.excel). You should have an ID for each menu item to use for click handling:
<item android:id="#+id/excel" />
if(item.getItemId() == R.id.excel) { ... }
Secondly there seems to be quite a bit of confusion here between the Toolbar and the Android action bar. You are you using a mixture of both in the code you have provided which is causing the inconsistency.
Firstly, if you're using a Toolbar in your layout, you don't need the action bar at all, therefore you should be inheriting from a NoActionBar Material Components theme (such as Theme.MaterialComponents.DayNight.NoActionBar). Then in order to setup your Toolbar you have two options:
Set the Toolbar as the action bar
With this approach you can register the Toolbar to act as the action bar for an activity, which means it correctly triggers the onOptionsItemSelected callback etc. So to do this we need to register it in onCreate:
setSupportActionBar(toolbar);
Then you should probably be using onCreateOptionsMenu to inflate the menu instead of Toolbar.inflateMenu just as you've already done in your code:
getMenuInflater().inflate(R.menu.excel, menu);
And finally to listen for menu item clicks, you can override onOptionsItemSelected and check the item ID as I outlined above.
Setup the Toolbar independently
Instead of registering the Toolbar as the action bar, you can instead just use the Toolbar like any regular view and set it up directly. Firstly to inflate the menu you can call:
toolbar.inflateMenu(R.menu.excel);
Then in order to listen for click events you can attach an OnMenuItemClickListener as follows:
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
...
}
});
Both approaches are valid but I personally prefer the second. It seems strange to try and work around the activity lifecycle when you could just treat the Toolbar normally.

Navigation View Selected Menu Item Checked In Other Activity?

i am Using Material Design Navigation View..i created Menu item And linked activity(Activity2.java) with an item(Starred)...and in that activity i extend my Main activity in which there is navigation view so that i can slide the navigation view from that activity too.. but when i slide the navigation view from the second activity the item is not checked and if i press the back button and go to the Main activity the previously checked menu item is shown...how to update the check item in other activity.please help
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in checked state
if(menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()){
//Replacing the main content with ContentFragment Which is our Inbox View;
case R.id.inbox:
Toast.makeText(getApplicationContext(),"Inbox Selected",Toast.LENGTH_SHORT).show();
ContentFragment fragment = new ContentFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
return true;
// For rest of the options we just show a toast on click
case R.id.starred:
startActivity(new Intent(MainActivity.this,Activity2.class));
drawerLayout.closeDrawers();
Toast.makeText(getApplicationContext(),"Stared Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.sent_mail:
Toast.makeText(getApplicationContext(),"Send Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.drafts:
Toast.makeText(getApplicationContext(),"Drafts Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.allmail:
Toast.makeText(getApplicationContext(),"All Mail Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.trash:
Toast.makeText(getApplicationContext(),"Trash Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.spam:
Toast.makeText(getApplicationContext(),"Spam Selected",Toast.LENGTH_SHORT).show();
return true;
default:
Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessay or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
}
Activity2.java
public class Activity2 extends MainActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frameLayout = (FrameLayout)findViewById(R.id.frame);
// inflate the custom activity layout
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater.inflate(R.layout.activity_2, null,false);
// add the custom layout of this activity to frame layout.
frameLayout.addView(activityView);
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/toolbar"
layout="#layout/tool_bar"
/>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="#layout/header"
app:menu="#menu/drawer"
/>
</android.support.v4.widget.DrawerLayout>
drawer.xml(menu_drawer)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/inbox"
android:checked="false"
android:icon="#drawable/ic_inbox_black"
android:title="#string/inbox_string" />
<item
android:id="#+id/starred"
android:checked="false"
android:icon="#drawable/ic_star_black"
android:title="#string/starred_string" />
<item
android:id="#+id/sent_mail"
android:checked="false"
android:icon="#drawable/ic_send_black"
android:title="#string/sent_mail_string" />
<item
android:id="#+id/drafts"
android:checked="false"
android:icon="#drawable/ic_drafts_black"
android:title="#string/draft_string" />
<item
android:id="#+id/allmail"
android:checked="false"
android:icon="#drawable/ic_email_black"
android:title="#string/all_mail_string" />
<item
android:id="#+id/trash"
android:checked="false"
android:icon="#drawable/ic_delete_black"
android:title="#string/trash_string" />
<item
android:id="#+id/spam"
android:checked="false"
android:icon="#drawable/ic_error_black"
android:title="#string/spam_string" />
</group>
</menu>
Add a protected int variable for storing id of checked menu item
From NavigationView's clickListener add checked menu item id to intent's extras; start yours second Activity with this intent
In second activity get menu item id from extras and set it to class variable from (see 1)
add onPrepareOptionsMenu in yours super-Activity
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
//recreate navigationView's menu, uncheck all items and set new checked item
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.drawer);
//setChecked(false) to all yours menu items in NavigationView
navigationView.getMenu().findItem(R.id.SOME_ID_0).setChecked(false);
navigationView.getMenu().findItem(R.id.SOME_ID_1).setChecked(false);
navigationView.getMenu().findItem(R.id.SOME_ID_2).setChecked(false);
...etc
navigationView.setCheckedItem(checkedDrawerItemId);
}
in yours NavigationView's clickListener do not forget to set clicked item's id to Activities class variable and call supportInvalidateOptionsMenu();
Try this in your Activity 2 :
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.starred).setChecked(true);
return true;
}

Custom icon in Android toolbar

I'm trying to use define a custom icon in the support Toolbar but the only icon shown is a left arrow... I tried to set it in the layout and programmatically but the result is the same.
Here is my Activity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
toolbar.setNavigationIcon(R.drawable.ic_launcher);
toolbar.setTitle("");
setSupportActionBar(toolbar);
}
And my toolbar layout
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/my_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:navigationIcon="#drawable/ic_action_bar"
android:minHeight="#dimen/action_bar_size"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
Just tried it myself and the issue seems to be that you have to call setNavigationIcon after setSupportActionBar(toolbar). Otherwise it'll only show the arrow as you've described.
So to fix this issue just change the code like this:
//...
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_launcher);
toolbar.setTitle("");
Note: Same goes for setting the title, contentDescription etc. I don't know if this a bug or if it is intended, but it's definitely kinda strange.
In case you want to change menu icon. (maybe somebody will need it)
In your activity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_info, menu);
return true;
}
in your menu folder in res. (menu_info.xml)
<?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/menu_info_action"
android:icon="#drawable/ic_info_icon"
android:title="#string/information"
app:showAsAction="ifRoom"/>
</menu>
The current most efficient way to achieve this:
first display the left hand side icon correctly, call this function in onCreateView or onCreate:
protected void enableDisplayHomeAsHome(boolean active) {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(active); // switch on the left hand icon
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_home); // replace with your custom icon
}
}
Now you can intercept this button press in your activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: { //index returned when home button pressed
homeButtonPressed();
return true;
}
}
return super.onOptionsItemSelected(item);
}
ActionBar.setHomeAsUpIndicator(...);
This one works for me.

How to set Navigation Drawer to be opened from right to left

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>
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 :)
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. ;)
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);
}
}
});
//...
}
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>
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
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.
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!
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.
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"
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"
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.
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);
}
}
});
//...
}
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
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:
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);
}
}
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.
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"

slide ExpandableListView at DrawerLayout form right to left

How to slide ExpandableListView at DrawerLayout form right to left
i want to show ExpandableListView at right corner of screen , how can i do that ??
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ExpandableListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="0dp"
/>
</android.support.v4.widget.DrawerLayout>
Change android:layout_gravity="start" to either android:layout_gravity="end" or android:layout_gravity="right" (using end will put the drawer on the left side of the screen for right-to-left configurations)
EDIT
It appears that the ActionBarDrawerToggle is looking for a drawer on the same side as the action bar Home icon (Gravity.START), which would be the left side for left-to-right layout directions. If you will always have the drawer on the right, you could do something like this:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawer, R.drawable.ic_drawer, R.string.open_drawer, R.string.close_drawer) {
#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 false;
}
};
If the drawer will always be opposite the action bar Home icon, you could use Gravity.END instead.
I have the same problem since my app is Arabic and must begin from the right.
After testing all solutions here, I found that the best is:
add this line in manifest : android:supportsRtl="true"
in your activity add this code : getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
in your listview don't use : android:layout_gravity="right"
because if you use right you get the error in more Android versions like 4.0.4
The solution is the use of: android:layout_gravity="start", because in this case the listview follows the gravity of the page.
It is a bug in the home button click in ActionBar that shows itself in line:
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
remove the lines I mentioned, where you have method:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
//....
}
and replace it with:
#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 true;
}
//...
}
Also do not forget to change the gravity of ListView to right: android:layout_gravity="right"

Categories

Resources