Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

enter image description here

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?

like image 600
Waza_Be Avatar asked Jun 16 '13 12:06

Waza_Be


People also ask

How do I get navigation drawer in all activity?

The user can view the navigation drawer when they swipe the activity's screen from the left edge of the android device. A user can also find it from the activity, by tapping the app icon (also known as the “hamburger” menu) in the action bar.

How does navigation drawer work?

The navigation drawer slides in from the left and contains the navigation destinations for the app. The user can view the navigation drawer when the user swipes a finger from the left edge of the activity. They can also find it from the home activity by tapping the app icon in the action bar.


2 Answers

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);     } } 
like image 188
jiahao Avatar answered Sep 21 '22 14:09

jiahao


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/

like image 33
methodin Avatar answered Sep 17 '22 14:09

methodin