【问题标题】:Android Navigation Drawer and windowActionBarOverlay = trueAndroid Navigation Drawer 和 windowActionBarOverlay = true
【发布时间】:2013-05-30 23:51:11
【问题描述】:

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

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

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

我已经做到了,但现在的问题是,由于内容正在扩展以利用使用 ActionBar 作为叠加层的额外空间,导航抽屉本身也在扩展,它与 ActionBar 重叠,创建一个看起来很糟糕的布局:

我想做的是实际内容(将填充片段的框架布局)占用额外空间,但导航抽屉仍位于操作栏下方,类似于播放音乐应用:

关于我可以做些什么来实现这一点的任何想法?

编辑 所以,根据 Ahmad 的帮助,我只在 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"
          />

现在,它在顶部效果很好,但由于某种原因,视图底部还有一个边距,这对我来说根本没有任何意义。 Here's a screenshot

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

【问题讨论】:

标签: android android-actionbar overlay navigation-drawer


【解决方案1】:

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

如果您将 ListView 重力设置为 start|bottom,它可以解决您的问题。底部没有添加额外的边距。看起来 DrawerLayout 默认重力是 start|center

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

【讨论】:

    【解决方案2】:

    如果有人对另一个问题感兴趣,请回答这个问题。这就是发生的事情。

    我尝试只设置列表视图顶部的边距,如下所示:

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

    但正如已编辑问题中所述,尽管没有在布局资源文件上设置,但它的行为很奇怪,底部也有边距。

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

    这就是我所做的:

    • 在ListView的顶部设置Padding,而不是margin:

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

    如前所述,请勿对尺寸进行硬编码,因为它们因设备而异。

    • 创建一个顶部透明的自定义可绘制对象,其余部分为纯色:

    它看起来像这样:

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

    请注意,我尝试在可绘制对象上使用?android:attr/actionBarSize,但这会使应用程序强制关闭。相反,我通过 grepcode 搜索并找到了几个不同大小的操作栏的 dimen 文件,因此我将它们添加到我自己项目的 dimen 文件中。

    • 对于值:48dp
    • 对于值域:40dp
    • 对于值-sw600dp:56dp

    在那之后,我觉得我看起来很棒,请注意屏幕截图上的列表视图和操作栏是如何不重叠的,并且列表视图的透明部分的大小恰到好处。

    希望对想知道如何实现这一目标的人有所帮助。

    【讨论】:

    • 我尝试了您的解决方案,但无法成功。背景是否设置为列表视图?
    • 你在哪里实现了“创建一个顶部透明的自定义可绘制对象,然后是纯色的其余部分”?
    【解决方案3】:

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

    只需将其添加到您的父布局中即可:

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

    属性actionBarSize 指的是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 音乐应用也是如此:

    【讨论】:

    • 那不会也设置框架布局的边距吗?并因此使片段的内容显示在操作栏下方?
    • 是的,这会将所有内容放在 ActionBar 下方
    • 没错,这会带来问题,因为我希望内容能够利用操作栏的透明度,这就是我开始使用叠加层的原因。我只希望抽屉位于操作栏下方。
    • 嘿艾哈迈德,你介意看看编辑过的问题吗?谢谢!
    • @daniel_c05 抱歉离线。但看起来你已经解决了这个问题。
    【解决方案4】:

    我使用 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>
    

    希望有帮助

    【讨论】:

      【解决方案5】:

      我按照上述指南创建了一个工作演示,并在 2.x 到 5.x 上进行了测试

      你可以从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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2013-05-24
        • 1970-01-01
        相关资源
        最近更新 更多