导航抽屉:在平板电脑上始终打开

我正在使用支持库中的导航抽屉模式: http : //developer.android.com/training/implementing-navigation/nav-drawer.html

我试图将其设置为始终在平板电脑上打开(作为侧边菜单)

在这里输入图像说明

这是目前的实现可能的东西,还是我们必须创build一个新的布局和一个新的结构与ListView,而不是重复使用相同的代码?

基于大型设备的想法可以有不同的布局文件,我创build了以下项目。

https://github.com/jiahaoliuliu/ABSherlockSlides

高光

由于大型设备的抽屉总是可见的,所以不需要抽屉。 相反,具有两个具有相同名称的元素的LinearLayout就足够了。

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

因为我们在布局文件中没有抽屉,当应用程序试图在布局中查找元素时,它将返回null。 所以,不需要额外的布尔值来查看哪个布局正在使用。

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

这里是将它用作布尔值的例子。

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

基于CommonsWare的答案,你可以做一些调整。 首先是设置以下三行:

 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); drawerLayout.setScrimColor(getResources().getColor(R.color.drawerNoShadow)); isDrawerLocked = true; 

drawerNoShadow颜色可以只是一个无alpha颜色(如0x00000000)。 这让你一个没有背景覆盖的抽屉。

你需要做的第二件事是调整你的FrameLayout的padding_left值。 为此,您可以设置一个维度来控制这个(默认为0dp) – 在这个例子中是R.dimen.drawerContentPadding。 您还需要一个R.dimen.drawerSize值,该值将是DrawerLayout的宽度。

这允许你检查FrameLayout的paddingLeft值来调用这些行。

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

然后,您可以将所有不想启用的function都包含在if(!isDrawerLocked)语句中。 这将包括:

  • drawerLayout.setDrawerListener(drawerToggle);
  • getActionBar().setDisplayHomeAsUpEnabled(true);

最后,您需要使用静态抽屉为视图设置备用布局。 一个例子是:

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

这里的美是你可以控制所有的逻辑,为你想要的设备设置替代的dimen.xml文件,唯一需要改变的是drawerContentPadding的值,并提供修改后的布局。

注:我结束了使用margin_left而不是padding_left,因为在新的布局覆盖了抽屉。 在http://derekrwoods.com/2013/09/creating-a-static-navigation-drawer-in-android/上查看更深入的博客文章;

尝试使用setDrawerLockMode()来locking在大屏幕设备上打开的抽屉。

正如我在评论中指出的,我不认为DrawerLayout是为你的场景而devise的(尽pipe这不是一个坏主意,恕我直言)。 可以使用不同的布局来托pipe相同的ListView和内容,也可以下载并修改您自己的DrawerLayout副本,在大屏幕设备上,将内容在打开时滑过而不是重叠。

基于@methodin示例代码和@CommonsWare的想法

这里是完整的代码 (仅限Android Studio)

以前的答案是好的,但在我的项目中实施时遇到一些问题,所以我想分享我的解决scheme。 首先,我们需要定义一个自定义的抽屉:

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

然后我们把它放在一个基本的活动布局(没有任何以前的答案任意布局),如下所示:

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

这里的内容填充是纵向的0dp,NavigationView的横向300dp(根据经验得出)。 我们在适当的values文件夹中定义它们:

values/dimens.xml

 <dimen name="content_padding">0dp</dimen> 

values-land/dimens.xml

 <dimen name="content_padding">300dp</dimen> 

最后,我们locking抽屉中的活动:

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