Android导航抽屉和windowActionBarOverlay = true

我试图在我的应用程序中实现新的Android导航抽屉。 我创build了一个处理抽屉设置和侦听器的BaseActivity.java,并且有两个子活动扩展了这个基类。 在第二项活动中,我打算使用不同的操作栏样式,使用以下attrs:

<item name="android:windowActionBarOverlay">true</item> <item name="android:background">@android:color/transparent</item> 

使操作栏透明,使内容更丰富,因为我的布局中有一个图片标题。

我已经实现了这一点,但现在的问题是,因为内容正在扩展,以利用作为覆盖使用的ActionBar额外的空间,导航抽屉本身也扩大了,它重叠的ActionBar,创造了一个非常糟糕的看布局:

在这里输入图像说明

我想要做的是实际的内容(将用一个片段填充的框架布局)占用额外的空间,但导航抽屉仍然在动作栏下面,类似于Play音乐应用程序:

在这里输入图像说明

任何想法,我可以做什么来实现这一目标?

编辑所以,根据艾哈迈德的援助,我只在ListView上设置marginTop 。 这是布局:

 <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_marginTop="?android:attr/actionBarSize" <!-- This was added after seeing the crazy effect, but does nothing --> android:layout_marginBottom="0dp" android:layout_marginLeft="0dp" android:layout_marginRight="0dp" android:layout_width="240dp" android:layout_height="fill_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:background="?attr/listviewBackground" /> 

而现在,它在顶端很好,但由于某种原因,在视图底部还有一个边缘,这对我来说根本没有任何意义。 这是一个截图 。

不知道是什么原因造成:(

Solutions Collecting From Web of "Android导航抽屉和windowActionBarOverlay = true"

而现在,它在顶端很好,但由于某种原因,在视图底部还有一个边缘,这对我来说根本没有任何意义。 这是一个截图。

如果你设置你的ListView重力开始|底部它解决了你的问题。 底部没有额外的保证金。 看起来像DrawerLayout默认的重力是开始|中心

 <ListView android:id="@+id/left_drawer" android:layout_marginTop="?android:attr/actionBarSize" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start|bottom"/> 

如果有人对另外一个感兴趣的话可以回答这个问题。 这是发生了什么事。

我试图设置只有边缘到列表视图的顶部像这样:

 android:layout_marginTop="?android:attr/actionBarSize" 

但正如编辑问题中提到的那样,尽pipe没有在布局资源文件上设置边界,但在底部还有一个边距的地方有一个奇怪的行为。

所以,我仔细观察了Play音乐应用程序,发现它实际上并不是一个边距,而是一些填充,另外他们还使用自定义背景填充由填充指定的空间,使用透明的颜色。

以下是我所做的:

  • 在ListView的顶部设置填充,而不是页边距:

    android:paddingTop="?android:attr/actionBarSize"

如前所述,每个设备的尺寸不同,重要的是不要对尺寸进行硬编码。

  • 创build一个自定义绘图,其顶部是透明的,然后是纯色的其余部分:

它看起来像这样:

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item> <shape android:shape="rectangle"> <solid android:color="#80000000" /> </shape> </item> <item android:top="@dimen/action_bar_default_height"> <shape android:shape="rectangle"> <solid android:color="@color/light_gray" /> </shape> </item> 

请注意,我试图在drawable上使用?android:attr/actionBarSize ,但是这使得app的closures。 相反,我通过grepcode进行search,发现了几个尺寸不同的用于操作栏的尺寸文件,所以我将它们添加到了我自己的项目的尺寸文件中。

  • 对于值:48dp
  • 价值土地:40dp
  • 对于值 – sw600dp:56dp

之后,我觉得我看起来很棒,注意截图中的listview和actionbar不重叠,listview的透明部分是正确的大小。

在这里输入图像说明

希望能帮助那些想知道如何实现这一点的人。

您可以在布局的顶部设置边距,以便内容在ActionBar下方自行绘制。

只需在您的父级布局中添加这个:

 android:layout_marginTop="?android:attr/actionBarSize" 

ActionBar的属性就像你已经猜到的那样,是指ActionBar的大小。 您不能将绝对值设置为保证金,因为ActionBar在所有Android设备中并不总是具有相同的尺寸(平板电脑的尺寸更大,手机设备的尺寸更小)。

编辑:

将边距设置为ListView

 <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_marginTop="?android:attr/actionBarSize" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start"/> </android.support.v4.widget.DrawerLayout> 

Google音乐应用也是这样做的:

在这里输入图像说明

我用paddingTop解决了这个问题:

 <FrameLayout android:id="@+id/menu_frame" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:paddingTop="?attr/actionBarSize" > <ListView android:id="@+id/left_drawer_list" android:layout_width="240dp" android:layout_height="match_parent" /> </FrameLayout> 

希望有所帮助

我已经按照上述指南创build了一个工作演示,并在2.x至5.x上进行了testing

你可以从Github克隆

重要的是玩“主要活动”

  toolbar = (Toolbar) findViewById(R.id.toolbar); res = this.getResources(); this.setSupportActionBar(toolbar); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout) findViewById(R.id.linearLayout); scrimInsetsFrameLayout.setOnInsetsCallback(this); } 

和回电

 @Override public void onInsetsChanged(Rect insets) { Toolbar toolbar = this.toolbar; ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); lp.topMargin = insets.top; int top = insets.top; insets.top += toolbar.getHeight(); toolbar.setLayoutParams(lp); insets.top = top; // revert } 

绝对的主题为V21做魔术

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- API 21 theme customizations can go here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/accent_material_light</item> <item name="windowActionModeOverlay">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowTranslucentStatus">true</item> </style>