Navigation Drawer: set as always opened on tablets - android

I am using the Navigation Drawer pattern from the support library:
http://developer.android.com/training/implementing-navigation/nav-drawer.html
I was trying to set it as always opened on tablet (as a side menu)
Is that something possible with the current implementation, or do we have to create a new layout and a new structure with a Listview instead of reusing the same code?

Based on the idea of larger devices could have different layout files, I have created the follow project.
https://github.com/jiahaoliuliu/ABSherlockSlides
HighLights:
Since the drawer of a large device is always visible, there is not need to have an drawer. Instead, a LinearLayout with two elements with the same name will be enough.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ListView
android:id="#+id/listview_drawer"
android:layout_width="#dimen/drawer_size"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#color/drawer_background"/>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/drawer_content_padding"
/>
</LinearLayout>
Because we don't have the drawer in the layout file, when the app try to find the element in the layout, it will return null. So, there is not need to have an extra boolean to see which layout is using.
DrawerLayout mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
if (mDrawerLayout != null) {
// Set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// Enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// ActionBarDrawerToggle ties together the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
public void onDrawerOpened(View drawerView) {
// Set the title on the action when drawer open
getSupportActionBar().setTitle(mDrawerTitle);
super.onDrawerOpened(drawerView);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
Here is the example to use it as boolean.
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (mDrawerLayout != null) {
mDrawerToggle.syncState();
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mDrawerLayout != null) {
// Pass any configuration change to the drawer toggles
mDrawerToggle.onConfigurationChanged(newConfig);
}
}

Building upon CommonsWare's answer you can do this with a couple of adjustments. The first is setting the following three lines:
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
isDrawerLocked = true;
The drawerNoShadow color can just be a no-alpha color (like 0x00000000). That gets you an open drawer with no background overlay.
The second thing you need to do is adjust the padding_left value of your FrameLayout. For this purpose you can setup a dimension to control this (0dp by default) - in this example R.dimen.drawerContentPadding. You will also need an R.dimen.drawerSize value that will be the width of the DrawerLayout.
This allows you to check the paddingLeft value of the FrameLayout to call those lines.
FrameLayout frameLayout = (FrameLayout)findViewById(R.id.content_frame);
if(frameLayout.getPaddingLeft() == (int)getResources().getDimension(R.dimen.drawerSize) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow));
isDrawerLocked = true;
}
You can then wrap all the functionality you don't want to enable in an if(!isDrawerLocked) statement. This will include:
drawerLayout.setDrawerListener(drawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
Lastly you do need to setup alternate layouts for the views with a static drawer. An example is:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="#dimen/drawerSize"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/drawerContentPadding"/>
The beauty here is you can then control all of the logic by setting up alternate dimen.xml files for the devices you want to target and the only thing you need to change is the value of drawerContentPadding and offer the modified layouts.
NOTE: I ended up using margin_left instead of padding_left since in the new layout it overlays the drawer. See a more in-depth blog post about the technique at http://derekrwoods.com/2013/09/creating-a-static-navigation-drawer-in-android/

Try setDrawerLockMode() to lock the drawer open on large-screen devices.
As I noted in a comment, I don't think that DrawerLayout is designed for your scenario (though it's not a bad idea, IMHO). Either use a different layout that hosts the same ListView and content, or perhaps download and modify your own copy of DrawerLayout that, on large-screen devices, slides the content over when opened rather than overlaps it.

Simply provide an alternate layout file for tablets. This way, you can save all the default behaviours of NavigationView.
Step 1
Simply create an alternate layout file similar to this for tablet devices and place it in layout-w600dp-land resource directory.
<?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="start">
<!--
NavigationView and the content is placed in a horizontal LinearLayout
rather than as the direct children of DrawerLayout.
This makes the NavigationView always visible.
-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.design.widget.NavigationView
android:id="#+id/nav"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"/>
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
Step 2
In this step we will be doing enough changes to make sure the opening and closing of drawer works only in non-tablet devices.
Step 2.1
Add the following content to a new value resource file in values directory and name it config_ui.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isDrawerFixed">false</bool>
</resources>
That was for non-tablet devices. For tablet devices, create another one with the same name and place it in values-w600dp-land.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isDrawerFixed">true</bool>
</resources>
Create a new field in the class of the activity the drawer belongs to as
private boolean isDrawerFixed;
and initialize it as
isDrawerFixed = getResources().getBoolean(R.bool.isDrawerFixed);.
Now we can check if the device is a tabled or a non-tablet as simple as if (isDrawerFixed){}.
Step 2.2
Wrap the code which sets up toggle button on the actionbar with an if statement like this.
if (!isDrawerFixed) {
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
Wrap the code which closes the drawer when an item is clicked with another if statement like this.
if (!isDrawerFixed) {
drawer.closeDrawer(GravityCompat.START);
}
The final result will look somewhat like this.

Previous answers are good, but I faced some problems while implementing them in my project, so I want to share my solution.
First of all, we need to define a custom drawer:
public class MyDrawerLayout extends DrawerLayout {
private boolean m_disallowIntercept;
public MyDrawerLayout (Context context) {
super(context);
}
#Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
// as the drawer intercepts all touches when it is opened
// we need this to let the content beneath the drawer to be touchable
return !m_disallowIntercept && super.onInterceptTouchEvent(ev);
}
#Override
public void setDrawerLockMode(int lockMode) {
super.setDrawerLockMode(lockMode);
// if the drawer is locked, then disallow interception
m_disallowIntercept = (lockMode == LOCK_MODE_LOCKED_OPEN);
}
}
Then we put it in a basic activity layout (without arbitrary layouts from previous answers) like this:
<MyDrawerLayout
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="start">
<!--We must define left padding for content-->
<FrameLayout
android:id="#+id/content_frame"
android:paddingStart="#dimen/content_padding"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/menu_nav" />
</MyDrawerLayout>
Content padding here is 0dp in portrait orientation and about 300dp in landscape for NavigationView (figured out empirically). We define them in appropriate values folders:
values/dimens.xml -
<dimen name="content_padding">0dp</dimen>
values-land/dimens.xml -
<dimen name="content_padding">300dp</dimen>
Finally, we lock the drawer in the activity:
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
mDrawerLayout.setScrimColor(0x00000000); // or Color.TRANSPARENT
isDrawerLocked = true;
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mDrawerLayout.setScrimColor(0x99000000); // default shadow
isDrawerLocked = false;
}

In 2022 & when using navigation component, it's enough to create alternate file, e.g. layout-w600dp-land/activity_navdrawer.xml
with such code (pay attention to where include is located):
<?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"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_navdrawer"
app:menu="#menu/activity_main_drawer" />
<include
android:id="#+id/app_bar_navdrawer"
layout="#layout/app_bar_navdrawer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>

Related

Android: setTitle inside RecyclerView addOnItemTouchListener is not working

[UPDATE BELOW]
I'm trying to change the title in the default title bar after clicking an item in the RecyclerView which is inside onLoadFinished (AsyncTaskLoader) but title doesn't change. The idea is when I tab an item in the RecyclerView and data is loaded, title bar text should be changed too but it doesn't.
catsRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, catsRecyclerView,new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
Categories category = categories.get(position);
int catId = category.getId();
setTitle(category.getTitle());
drawerLayout.closeDrawer(GravityCompat.START);
commonActions(); //restarting loader and executing other methods
}
#Override
public void onLongClick(View view, int position) {
}
}));
When I log category.getTitle() I get the correct text but title doesn't change how can I achieve that?
[Update]
Replaced the default title bar with a custom action bar here's the layout of the activity:
<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="start">
<include layout="#layout/actionbar"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
The actiobar 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:layout_width="match_parent"
android:layout_height="40dp"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:id="#+id/primaryToolbar">
</android.support.v7.widget.Toolbar>
The activity
toolbar = findViewById(R.id.primaryToolbar);
setSupportActionBar(toolbar);
setTitle("My new title");
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
But it's size is so large taking the whole screen
I think the problem is in the listener. When I attach a listener to recycler view I do it throughout Using interface in adapter, this blog shows the way, also check out this StackOverflow answer in which and example is provided.
You have to enable the action bar to setTitle() by setting the following flag.
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
The above code works for AppCompatActivity.
I had 2 issues. The first one is about not changing the title of the titlebar after tabbing an item in the RecyclerView to reload the AsyncTaskLoader. The problem is there's another setTitle in the Loader function in addition to onLoadFinished so I removed it and kept the one inside onLoadFinished and now it's working fine so there's no need to replace the default title bar with the action bar.
The second issue when I tried to add the action bar, the title was taking the whole screen as you see in the image because there are 2 elements in the root view which are the actionBar and the NavigationView which made the actionBar the actual content that's why it was resized to take the whole screen. So i placed it inside a LinearLayout and the actual content goes below it that fixed the second problem

Pushing the mainActivity to the side When the Navigation Drawer Opens

Currently, when the navigation drawer in my app opens, it appears on top of the mainActivity view.
My question being, is it possible to animate the mainActivity view so that the left side of said view matches the right side of the navigation drawer when it opens?
It is (almost) always possible. But i think it is a bad idea, as it will not follow the ui guidelines from google for an android app.
However if you really want to do it, you have two options :
Easy. When the drawer is open start animation on the rest of the layout, and do the opposite animation when the drawer is closed. It is less effort, but probably poor result.
Implement your own drawer. You will be able to have the perfect animation and behavior you desire. In this case you probably want to use fragment. The main fragment will be the content and another fragment will be the drawer. When you need to do it, you can animate both fragment with a translation to "open" your drawer.
You can read more about animation here.
All you have to do is setX() of your main_content in the Activity
my_activity.xml
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<RelativeLayout
android:id="#+id/main_content_rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/material_grey_100">
<include
layout="#layout/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
<!-- The navigation drawer -->
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/menu_drawer"/>
</android.support.v4.widget.DrawerLayout>
MyActivity java file
mDrawerToggle =
new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open,
R.string.drawer_close) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
float width = drawerView.findViewById(R.id.main_header_rl).getWidth();
final int movement= (int) (width * slideOffset);
findViewById(R.id.main_content_rl).setX(movement);
super.onDrawerSlide(drawerView, slideOffset);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
Where main_header_rl is the id of my header_navigation_drawer
<RelativeLayout
android:id="#+id/main_header_rl"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
...
</RelativeLayout>

Layout behind status bar - Android Lollipop

I want in my application to be able to implement this effect:
where the status bar is semi transparent and the layout is behind the status bar. Every example that I've read on the subject, was mainly associated with the navigation drawer and mostly used the ScrimInsetScrollView (or ScrimInsetsFrameLayout). I tried implementing this with ScrimInsetsFrameLayout.
Basically I have an activity that holds a fragment, and this is my layout (the fragment is later added to the container in the activity's onCreate method):
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
>
<com.test.app.widget.ScrimInsetsFrameLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:insetForeground="#4000"
android:id="#+id/container"
></com.test.app.widget.ScrimInsetsFrameLayout>
</FrameLayout>
And also I've set the android:statusBarColor to transparent in themes.
The solution does not work for me. Apparently I am doing something wrong here.
Can someone point out where I am mistaken?
Have you tried
#Override
public void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
as described in the Android documentation

Android 5.0 material design style navigation drawer for KitKat

I see that Android introduced new navigation drawer icons, drawer icon and back arrow icon. How can we use that in Kitkat supported apps. See Google's latest version of Newsstand app, which has the latest navigation drawer icons and animations. How can we implement that?
I have tried setting the minSDK to 19 and complileSDK to 21 but it's using the old style icons. Is that self implemented?
You need to use the new Toolbar in the appcompat v21 and the new ActionBarDrawerToggle that is in this library as well.
Add the gradle dependency to your gradle file:
compile 'com.android.support:appcompat-v7:21.0.0'
Your activity_main.xml layout would look something like that:
<!--I use android:fitsSystemWindows because I am changing the color of the statusbar as well-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<include layout="#layout/toolbar"/>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main layout -->
<FrameLayout
android:id="#+id/main_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Nav drawer -->
<fragment
android:id="#+id/fragment_drawer"
android:name="com.example.packagename.DrawerFragment"
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="left|start" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Your Toolbar layout would look something like that:
<?xml version="1.0" encoding="utf-8"?>
<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/toolbar"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
Your activity must extend from:
ActionBarActivity
When you find your views (drawer and toolbar) in the activity the set the toolbar as the support action bar and set the setDrawerListener:
setSupportActionBar(mToolbar);
mDrawerToggle= new ActionBarDrawerToggle(this, mDrawerLayout,mToolbar, R.string.app_name, R.string.app_name);
mDrawerLayout.setDrawerListener(mDrawerToggle);
After that you just need to take care of the menu items and drawerToogle state:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.menu_main,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onBackPressed() {
if(mDrawerLayout.isDrawerOpen(Gravity.START|Gravity.LEFT)){
mDrawerLayout.closeDrawers();
return;
}
super.onBackPressed();
}
The implementation is the same as It was before the Toolbar and you receive the arrow animation for free. No headaches. For more information follow:
The documentation.
The ChrisBanes post
The official android blog post.
If you want to display the drawer over the Toolbar and under the status bar, please refer to this question.
EDIT: Use NavigationView from the support design library. Tutorial to learn how to use in here: http://antonioleiva.com/navigation-view/
The answer is no longer useful. Leaving it here for only historic purpose as the time of posting Android did not have the implementation :)
There are plenty of libraries now that can achieve this.
Choice 1 - https://github.com/neokree/MaterialNavigationDrawer
Others
https://github.com/HeinrichReimer/material-drawer
https://github.com/kanytu/android-material-drawer-template
https://github.com/balysv/material-menu
https://github.com/ikimuhendis/LDrawer
https://github.com/Zlate87/material-navigation-drawer-example
If you want the real navigation drawer with material design style (defined here) I have implemented a custom library that do exactly that.
You can find it here
Supporting top comment along with the new generated main_content's layout. I simply override the included content layout with DrawerLayout. Keep in mind that your drawerlayout must have this layout_behavior: appbar_scrolling_view_behavior
top container's layout
https://github.com/juanmendez/jm_android_dev/blob/master/01.fragments/06.fragments_with_rx/app/src/main/res/layout/activity_recycler.xml#L17
included content layout
https://github.com/juanmendez/jm_android_dev/blob/master/01.fragments/06.fragments_with_rx/app/src/main/res/layout/content_recycler.xml#L9

Close navigation drawer in Android by tapping on the empty portion of the screen

I have navigation drawer in my Android app and its visibility is controlled by the App icon in the Action Bar. However, I need to be able to close the drawer not only by tapping the app icon but also if the user taps on the empty (non-occupied) portion of the screen. This is my main layout:
<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" />
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:background="#color/white"
style="#style/ListViewSeparator"/>
I don't understand which layout is the one I need to set a listener to, because when I open the navigation drawer it contains my '240dp' listview, but the rest of the screen becomes like 'transparent black', I am looking for that 'transparent black' layout which is the rest of the screen
Found it:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
it was set to LOCK_MODE_LOCKED_OPENED before
Depends on your interests. Based on the Google Examples, i implemented the same using this code:
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
...
#Override
public void onItemClick(AdapterView<?> adapterView, View v, int position, long arg3) {
selectItem(position);
mDrawerList.setItemChecked(position, true);
mDrawerLayout.closeDrawer(mDrawerList);
}

Categories

Resources