Android Navigation Drawer(DrawerLayout) is hidden by content view - android

I have a Navigation Drawer issue.
On my Navigation Drawer app, sometimes Drawer is displayed behind the other content view. So only the part of the drawer is shown (the other parts are hidden by content area).
I tried everything but it does not works.
drawer.bringToFront();
drawer.buildLayer();
drawer.clearFocus();
drawer.requestLayout();
drawer.forceLayout();
But in this situation, if I touch option button or change focus, screen is refreshed and it displays drawer well.
So I want to know what kinds of methods are called when I touch option button. Then I think I can call that method when drawer is opened.
Thank you so much in advanced.

I am posting a sample code try to check with your code.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<RelativeLayout
android:id="#+id/relative_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/tile_image_data" >
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="48dip" >
</android.support.v4.view.ViewPager>
</RelativeLayout>
<ListView
android:id="#+id/drawer"
android:layout_width="240dp"
android:layout_height="fill_parent"
android:layout_gravity="right"
android:cacheColorHint="#00000000"
android:divider="#19000000"
android:background="#drawable/tile_image_data"
android:choiceMode="singleChoice" />
</android.support.v4.widget.DrawerLayout>

I had the same problem. I solved it by changing android:id in the FrameLayout from #android:id/content to #+id/content. Apparently it's not always a good idea to use system resource ids.

I had the same problem. When the main view called onWindowsFocusChange() the drawer opened behind the main view. This happened with a Unity3D view.
I've solved the issue calling in the function
onDrawerSlide(View drawerView, float slideOffset)
,which is a method inside the DrawerListener, drawerView.bringToFront().

I had the same problem, but it seems that it just only happen on versions prior KITKAT. Thanks to #jack, after I updated the code following, it is ok:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open,
R.string.drawer_close) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
drawerView.bringToFront();
getWindow().getDecorView().requestLayout();
getWindow().getDecorView().invalidate();
}
}
};
You may want to know why do I invoke requestLayout() and invalidate(), just see the doc for bringToFront().

Related

How to make a background image moving when user scroll a view on android

Hello developer and programmers. I just start learning android app development. Found awesome navigation bar style and want to develop similar design. It has background image and it moves when scroll.
Please help me to develop the same. Thanks. I added an example gif as link.
https://media.giphy.com/media/l4FGv7VknT1zpZACQ/giphy.gif
This can be achieved by using a custom layout for your navigation drawer alongside a custom implementation of DrawerLayout.DrawerListener. Below is a very simple example that can be easily adapted to the code generated by Android Studio's "New Project -> Navigation Drawer Activity".
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="#+id/nav_view"
android:layout_width="#dimen/navdrawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ccc">
<ImageView
android:id="#+id/image"
android:layout_width="256dp"
android:layout_height="256dp"
android:layout_gravity="center"
android:src="#drawable/mydrawable"/>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.image);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
DrawerLayout.DrawerListener listener = new MyActionBarDrawerListener();
drawer.addDrawerListener(listener);
}
private class MyActionBarDrawerListener extends DrawerLayout.SimpleDrawerListener {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
int navdrawerWidth = getResources().getDimensionPixelSize(R.dimen.navdrawer_width);
float closedAmount = (1 - slideOffset);
int marginStart = 2 * (int) (navdrawerWidth * closedAmount);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) iv.getLayoutParams();
MarginLayoutParamsCompat.setMarginStart(params, marginStart);
iv.setLayoutParams(params);
}
}
}
The core of the solution is that you provide a background image but update its marginStart attribute as the drawer slides. You can fiddle with the exact numbers to get the amount of sliding that you like.
Note that I've omitted a lot of code in order to improve readability. In practice you would probably have MyActionBarDrawerListener extend from ActionBarDrawerToggle so that you'd get the navigation icon etc.
Look it's not that hard but still it's not that easy Because this type of effect is said to be Parallax effect. I done a solid googling but still can't find a helpful library. So you have to do this your self
Steps are
Learn about custom navigation layout which is made by your fragment.
Once you are done with drawer layout add an Image as a background of your fragment
call mSlidingDrawer.addDrawerListner(new YourDrawerListner()) method // just like Ben P.
Implement onDrawerSlide(View drawerView, float slideOffset)
get the Your Fragment Background Image Instance (I used mImage)
in onDrawerSlide(...) use offset
In your image instance call mImage.animate().setTranslationX(offset).start()
Update
Ben P. answer is better But you can use mine also just add the DrawerListner part of Ben P. to my answer also
Core
It is parallax effect. based on relative motion of elements

Permanent NavigationView loose focus after an item is selected

I started a project with a Navigation Drawer from the basic template of Android Studio. The only modification I made was to display it as permanent in order to have a tablet/TV layout.
To achieve this, the only modification I made was in the xml layout. This allow the NavigationView to be always visible.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Content will come here" />
</LinearLayout>
</LinearLayout>
I also put the project on Github, so anyone can test it.
PROJECT DEMO ON GITHUB
https://github.com/ChristopheVersieux/NavFocus
WHAT IS HAPPENING
My issue comes when I start selecting items on the drawer with the D-pad.
Once an item is selected, the focus is completely lost. Trying to get back to the Drawer and get focus seems very hard and I have to try several times with right/left arrows
WHAT IS EXPECTED:
Drawer should keep focus, or focus should be easy to bring back to the Drawer.
WHAT I TRIED:
The simplest Idea I had was to force the Drawer to get focus again, but this code doesn't change anything:
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
//This is where I will replace the Fragments in the right area.
navigationView.clearFocus();
navigationView.requestFocus();
return true;
}
});
Thank a lot for your help.
I would start by removing android:layout_gravity="start"
This is simply not needed as its parent is a horizontal LinearLayout.
The Navigation Drawer must be permanently visible on Tablets and TV. They stay hidden for mobile. These are part of the Material Design guidelines.
This requires quite a different setup compared to what I see in your project on GitHub. Which includes supplying different resources using qualifiers.
This tutorial on Navigation Drawer (Design Support) will help you with exactly that setup, as per the latest Material Design guidelines. Alternatively the project files for the tutorial can be found on GitHub.
UPDATE:
As pointed out, Support library v24 creates issues with the dpad. Reverting to v23 works just fine.

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>

navigation drawer google maps v2 , map blocking drawer

I have this problem when opening drawer on gingerbread and behind is google map v2. Map that should be on screen behind gets on top of everything.
Now I could bypass this by hiding map when drawer opens and show it when closes but I'm looking for more elegant solution if someone came up with any?
Just wrap SupportMapFragment with FrameLayout and put transparent View above like this:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Map fragment -->
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
<!-- Transparent view -->
<View
android:layout_width="match_parent"
android:layout_height="match_parent" />
Tested with Android 4.0.4 - works fine for me
There is a bug with google maps api v2 and black space. Maybe you have got similar problem. For solutions look here:
https://github.com/jfeinstein10/SlidingMenu/issues/228
and here:
https://github.com/jfeinstein10/SlidingMenu/issues/168
As far as I remember solutions are one of this:
extending Google Maps and make it to redraw every view more often
set map's z index on top param to true
put transparent overlay over Google Maps view
I have got the same problem here on ICS 4.0.4. The solutions mentioned in jfeinstein10's github post seems not working for me. But I have found a workaround, even it is not the best.
When creating DrawerToggle object I override this event
#Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
super.onDrawerSlide(drawerView, slideOffset);
mDrawerLayout.bringChildToFront(drawerView);
mDrawerLayout.requestLayout();
mDrawerLayout.setScrimColor(Color.TRANSPARENT);
}
bringChildToFront and requestLayout method should overcome the drawer rendering problem while setScrimColor will get rid of the shadow. Too bad that I haven't found a workaround to render the shadow correctly as well. Hope this helps.
You should override the onDrawerSlide function and move the drawer to front
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
DrawerLayout Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, Drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
super.onDrawerSlide(drawerView, slideOffset);
Drawer.bringChildToFront(drawerView);
Drawer.requestLayout();
Drawer.setScrimColor(Color.TRANSPARENT);
}
};

Navigation Drawer: set as always opened on tablets

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>

Categories

Resources