如何使用DrawerLayout在操作栏/工具栏上方和状态栏下方显示?


394

我在新的材质设计Side Nav规范中看到,可以在操作栏上方和状态栏后面显示抽屉。我该如何实施?


4
即使到了今天,仍然没有一个明确的答案可以解决向后兼容问题。这些问题确实使任何程序员感到愤怒。已经在Android系统中推广“ N” API和许多基本方面以进行改进。
Val Martinez

Answers:


528

框架和支持库中的新功能完全可以做到这一点。一共有三个“谜题”:

  1. 使用工具栏,以便您可以将操作栏嵌入到视图层次结构中。
  2. 制作DrawerLayout fitsSystemWindows,使其布置在系统栏后面。
  3. 禁用Theme.Material的正常状态栏着色,以便DrawerLayout可以在此处绘制。

我假设您将使用新的appcompat。

首先,您的布局应如下所示:

<!-- The important thing to note here is the added fitSystemWindows -->
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Your normal content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <android.support.v7.widget.Toolbar  
            android:id="@+id/my_awesome_toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />

        <!-- The rest of your content view -->

    </LinearLayout>

    <!-- Your drawer view. This can be any view, LinearLayout
         is just an example. As we have set fitSystemWindows=true
         this will be displayed under the status bar. -->
    <LinearLayout
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="left|start"
        android:fitsSystemWindows="true">

        <!-- Your drawer content -->

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

然后在您的活动/片段中:

public void onCreate(Bundled savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Your normal setup. Blah blah ...

    // As we're using a Toolbar, we should retrieve it and set it
    // to be our ActionBar
    Toolbar toolbar = (...) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

    // Now retrieve the DrawerLayout so that we can set the status bar color.
    // This only takes effect on Lollipop, or when using translucentStatusBar
    // on KitKat.
    DrawerLayout drawerLayout = (...) findViewById(R.id.my_drawer_layout);
    drawerLayout.setStatusBarBackgroundColor(yourChosenColor);
}

然后,您需要确保DrawerLayout在状态栏后面可见。您可以通过更改values-v21主题来做到这一点:

values-v21 / themes.xml

<style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

注意:如果使用a <fragment android:name="fragments.NavigationDrawerFragment">代替

<LinearLayout
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="left|start"
    android:fitsSystemWindows="true">

    <!-- Your drawer content -->

</LinearLayout>

实际的布局,如果您调用fitsSystemWindows(boolean)onCreateView方法返回的视图,则将达到预期的效果。

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container,
                         Bundle savedInstanceState) {
    View mDrawerListView = inflater.inflate(
        R.layout.fragment_navigation_drawer, container, false);
    mDrawerListView.setFitsSystemWindows(true);
    return mDrawerListView;
}

3
是的,DrawerLayout需要将其布置在系统栏的后面。然后,您需要将其设置在抽屉视图中,以便DrawerLayout将其布置在窗口插图中。
克里斯·巴内斯

11
根本无法解决这个问题。使用上面的代码在新的演示应用程序中,结果看起来类似于@ScootrNova描述的结果。观看此屏幕截图:imgur.com/QLk3syt
Michael Schmidt

6
看起来您实际上需要layout_marginTop在抽屉内容布局的根目录中使用负号。否则,您抽屉内容的布局背景将被绘制在状态栏的顶部,其他所有内容将被下推。然而,据我所知,这似乎是一个总的解决方案,据我所知,没有?attr / statusBarSize或类似Android提供的任何东西。
2014年

26
为了获得通过状态栏可见抽屉的效果,我最终在DrawerLayout上将android:fitsSystemWindows设置为false,在主内容布局(包含工具栏的布局)上将android:fitsSystemWindows设置为true,并添加<item name =“ android:windowTranslucentStatus”>是我的主题的真</ item>-在棒棒糖上
Jakob

8
这个答案是不完整的。您还需要将导航抽屉包装在ScrimLayout中。请参阅stackoverflow.com/a/26926998/174149
Markus Hi

138

编辑:新的设计支持库支持此,并且不再需要以前的方法。

现在,可以使用新的Android设计支持库来实现。

您可以看到Chris Banes 的Cheesesquare示例应用程序,其中演示了所有新功能。


以前的方法:

由于没有发布完整的解决方案,因此这是我获得期望结果的方法。

首先在您的项目中包含一个ScrimInsetsFrameLayout

/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* A layout that draws something in the insets passed to 
* {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
* (status and navigation bars, overlay action bars).
*/
public class ScrimInsetsFrameLayout extends FrameLayout {
    private Drawable mInsetForeground;

    private Rect mInsets;
    private Rect mTempRect = new Rect();
    private OnInsetsCallback mOnInsetsCallback;

    public ScrimInsetsFrameLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public ScrimInsetsFrameLayout(
        Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ScrimInsetsView, defStyle, 0);
        if (a == null) {
            return;
        }
        mInsetForeground = a.getDrawable(
            R.styleable.ScrimInsetsView_insetForeground);
        a.recycle();

        setWillNotDraw(true);
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        mInsets = new Rect(insets);
        setWillNotDraw(mInsetForeground == null);
        ViewCompat.postInvalidateOnAnimation(this);
        if (mOnInsetsCallback != null) {
            mOnInsetsCallback.onInsetsChanged(insets);
        }
        return true; // consume insets
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        int width = getWidth();
        int height = getHeight();
        if (mInsets != null && mInsetForeground != null) {
            int sc = canvas.save();
            canvas.translate(getScrollX(), getScrollY());

            // Top
            mTempRect.set(0, 0, width, mInsets.top);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Bottom
            mTempRect.set(0, height - mInsets.bottom, width, height);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Left
            mTempRect.set(
                0, 
                mInsets.top, 
                mInsets.left, 
                height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            // Right
            mTempRect.set(
                width - mInsets.right, 
                mInsets.top, width, 
                height - mInsets.bottom);
            mInsetForeground.setBounds(mTempRect);
            mInsetForeground.draw(canvas);

            canvas.restoreToCount(sc);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(this);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mInsetForeground != null) {
            mInsetForeground.setCallback(null);
        }
    }

    /**
     * Allows the calling container to specify a callback for custom 
     * processing when insets change (i.e. when {@link #fitSystemWindows(Rect)}
     * is called. This is useful for setting padding on UI elements 
     * based on UI chrome insets (e.g. a Google Map or a ListView). 
     * When using with ListView or GridView, remember to set
     * clipToPadding to false.
     */
    public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
        mOnInsetsCallback = onInsetsCallback;
    }

    public static interface OnInsetsCallback {
        public void onInsetsChanged(Rect insets);
    }
}

然后创建一个可样式化以便insetForeground可以设置。

values / attrs.xml

<declare-styleable name="ScrimInsetsView">
    <attr name="insetForeground" format="reference|color" />
</declare-styleable>

更新您的活动的XML文件,并确保android:fitsSystemWindows设置为true上都DrawerLayout还有ScrimInsetsFrameLayout

layout / activity_main.xml

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <!-- The main content view -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Your main content -->

    </LinearLayout>

    <!-- The navigation drawer -->
    <com.example.app.util.ScrimInsetsFrameLayout 
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/scrimInsetsFrameLayout"
        android:layout_width="320dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/white"
        android:elevation="10dp"
        android:fitsSystemWindows="true"
        app:insetForeground="#4000">

        <!-- Your drawer content -->

    </com.example.app.util.ScrimInsetsFrameLayout>

</android.support.v4.widget.DrawerLayout>

在活动的onCreate方法内,在抽屉布局中设置状态栏背景色。

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ...

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    mDrawerLayout.setStatusBarBackgroundColor(
        getResources().getColor(R.color.primary_dark));
}

最后,更新您应用的主题,使其DrawerLayout位于状态栏的后面。

values-v21 / styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

结果:


10
这对我来说效果最好。我花了2天的时间来完成此工作,这就是其中之一。这应该标记为答案。非常感谢。
kalehv 2014年

2
我没有使用appcompat,所以没有用。:(有没有指导者可以在没有appcompat的情况下使它正常工作?
Jared Rummler

3
这是最完美的答案。我已经在从4.X到5.X的各种Android设备中实现并测试了它,并且可以确认它是否完美运行。非常感谢。
Aritra Roy 2015年

2
就像我说的那样,它可以完美运行,但是我有一个小问题。导航抽屉中的活动具有透明的状态栏,但是所有其他活动都从状态栏中丢失了“ primaryDark”颜色。如何找回呢?
Aritra Roy 2015年

5
我花了三天的时间才接受到,除了使用围绕抽屉碎片包裹的这种额外布局之外,目前别无其他方法。否则,状态栏将为灰色(第一个孩子的背景颜色),或者抽屉将显示在状态栏下方。
丹尼斯

96

随着最新的Android支持库(22.2.0版)的发布,我们有了一个设计支持库,并且在其中包含了一个名为NavigationView的新视图。因此,我们无需ScrimInsetsFrameLayout仅使用和其他所有东西来独自完成所有工作,而只需使用此视图即可完成所有工作。

步骤1

将添加Design Support Library到您的build.gradle文件

dependencies {
    // Other dependencies like appcompat
    compile 'com.android.support:design:22.2.0'
}

第2步

将添加NavigationView到您的DrawerLayout

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true"> <!-- this is important -->

     <!-- Your contents -->

     <android.support.design.widget.NavigationView
         android:id="@+id/navigation"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_gravity="start"
         app:menu="@menu/navigation_items" /> <!-- The items to display -->
 </android.support.v4.widget.DrawerLayout>

第三步

在中创建一个新的菜单资源,/res/menu并添加要显示的项目和图标:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_action_home"
            android:title="Home" />
        <item
            android:id="@+id/nav_example_item_1"
            android:icon="@drawable/ic_action_dashboard"
            android:title="Example Item #1" />
    </group>

    <item android:title="Sub items">
        <menu>
            <item
                android:id="@+id/nav_example_sub_item_1"
                android:title="Example Sub Item #1" />
        </menu>
    </item>

</menu>

第四步

初始化NavigationView并处理单击事件:

public class MainActivity extends AppCompatActivity {

    NavigationView mNavigationView;
    DrawerLayout mDrawerLayout;

    // Other stuff

    private void init() {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mDrawerLayout.closeDrawers();
                menuItem.setChecked(true);
                switch (menuItem.getItemId()) {
                    case R.id.nav_home:
                        // TODO - Do something
                        break;
                    // TODO - Handle other items
                }
                return true;
            }
        });
    }
}

第5步

一定要设置android:windowDrawsSystemBarBackgroundsandroid:statusBarColorvalues-v21否则你的抽屉那倒显示“下的”状态栏

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Other attributes like colorPrimary, colorAccent etc. -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

可选步骤

将标题添加到NavigationView。为此,只需创建一个新的布局并添加app:headerLayout="@layout/my_header_layout"到NavigationView。

结果

该图显示了导航视图

笔记

  • 所述突出颜色使用经由所述定义的颜色colorPrimary属性
  • 列表项使用的颜色通过定义的textColorPrimary属性
  • 图标使用颜色通过定义的textColorSecondary属性

您还可以检查Chris Banes示例应用程序,该应用程序突出显示了NavigationView以及属于设计支持库的其他新视图(例如FloatingActionButtonTextInputLayoutSnackbarTabLayout等)。


1
谢谢@reVerse !! >如果要更新样式文件中列表中的每个项目和图标,则可以使用以下方法进行:<item name="itemTextColor">@color/YOUR_COLOR</item> <item name="itemIconTint">@color/YOUR_COLOR</item>
Juan Saravia 2015年

如何更改所选项目的背景颜色?
2015年

2
这种方法仍然会在ActionBar后面生成NavigationView。
萨瑟顿

1
@southerton当然,您必须使用Toolbar-无法使用ActionBar
reVerse 2015年

1
@ reegan29只需致电即可mDrawerLayout.openDrawer(GravityCompat.START);。如果您使用的ActionBarDrawerToggle是汉堡包,则应在点击汉堡包图标后立即自动进行。
2015年

6

使它工作,在values-v21样式或主题xml中需要使用此属性:

<item name="android:windowTranslucentStatus">true</item>

那使魔术!


3
这也使我的操作栏也显示在状态栏的后面。
米歇尔2014年

但这就是我们试图实现的效果,看看Gmail 5.0应用程序?它在状态栏后面显示侧边栏。
Nicolas Jafelle 2014年

那不是我的意思。即使导航抽屉位于此代码行的状态栏后面,工具栏/操作栏也是如此。
米歇尔2014年

2
发布者和回答者是设计AppCompat的Google员工,所以我很确定他在编写内容时知道他在做什么。
afollestad

@Mixx,您可以为常规内容视图设置android:fitsSystemWindows =“ true”(例如,如果采用可接受的答案布局)。即使适用于Android 4.4,它也可以工作。但这里有一点区别:在Android 5.0中,状态栏上的透明度级别(比Alpha值更高)(比Alpha值更高),使状态栏更暗。
前千2014年

6

以上所有方法都是正确的,可能正在起作用。我已经按照上述指南创建了一个工作演示,并在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>

和ScrimInsetsFrameLayout

现在,有了新功能,这变得更加容易 设计支持库,

compile 'com.android.support:design:22.2.0'

从@Chris Banes克隆 https://github.com/chrisbanes/cheesesquare


4

这里提到的所有答案都太旧太冗长。与最新Navigationview一起使用的最佳和简短解决方案是

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
    super.onDrawerSlide(drawerView, slideOffset);

    try {
        //int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
            // Do something for lollipop and above versions

        Window window = getWindow();

        // clear FLAG_TRANSLUCENT_STATUS flag:
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

        // finally change the color to any color with transparency

         window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDarktrans));}

    } catch (Exception e) {

        Crashlytics.logException(e);

    }
}

这将在打开抽屉时将状态栏颜色更改为透明

现在,当您关闭抽屉时,您需要再次将状态栏颜色更改为暗色,因此您可以通过这种方式进行操作。

        public void onDrawerClosed(View drawerView) {
        super.onDrawerClosed(drawerView);
        try {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
    // Do something for lollipop and above versions

    Window window = getWindow();

    // clear FLAG_TRANSLUCENT_STATUS flag:
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

    // finally change the color again to dark
    window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));}
    } catch (Exception e) {
    Crashlytics.logException(e);
                    }
                    }

然后在主布局中添加一行

            android:fitsSystemWindows="true"

您的抽屉布局看起来像

            <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:fitsSystemWindows="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

您的导航视图将看起来像

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/navigation_header"
        app:menu="@menu/drawer"
        />

我已经对其进行了测试,并且可以正常工作,希望它对某人有所帮助。标记它是否有帮助。快乐编码:)


另外,如果在ActionBar中使用自定义视图,则可以在onDrawerSlide()中将自定义视图的可见性设置为INVISIBLE,在onDrawerClosed()中将其设置为VISIBLE。
米兰

3

我正在使用设计支持库。仅通过使用自定义主题,当打开导航抽屉时,我就获得了透明的状态栏。

在此处输入图片说明

在此处输入图片说明

<style name="NavigationStyle" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>

    <!-- To Make Navigation Drawer Fill Status Bar and become Transparent Too -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>

</style>

最后在清单文件中添加主题

<activity
  ........
  ........
 android:theme="@style/NavigationStyle"> 
</activity>

不要忘记android:fitsSystemWindows="true"在“ DrawerLayout”中使用该属性


1
如何将其用于api 19级设备?
AndroidGuy 2015年

2

这是最简单的,对我有用:

在值21中:

<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        ...
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    <dimen name="topMargin">25dp</dimen>
</resources>

在值中:

<resources>
    <dimen name="topMargin">0dp</dimen>
</resources>

并设置到您的工具栏

android:layout_marginTop="@dimen/topMargin"

我也这样做了,它就像棒棒糖上的魅力。但是我用24dp最高利润。
拉法,2015年

当您在装有Android 7.1的设备上划分屏幕时,如果应用程序是屏幕的第二部分,则可以在顶部看到该间隙。
西塞罗·莫拉

1

而不是使用ScrimInsetsFrameLayout...。添加固定高度为24dp,背景为的视图是否更容易primaryColor

我知道这涉及在层次结构中添加虚拟视图,但对我来说似乎更干净。

我已经尝试过了,效果很好。

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_base_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- THIS IS THE VIEW I'M TALKING ABOUT... -->
        <View
            android:layout_width="match_parent"
            android:layout_height="24dp"
            android:background="?attr/colorPrimary" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/activity_base_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:elevation="2dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark" />

        <FrameLayout
            android:id="@+id/activity_base_content_frame_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

    <fragment
        android:id="@+id/activity_base_drawer_fragment"
        android:name="com.myapp.drawer.ui.DrawerFragment"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:elevation="4dp"
        tools:layout="@layout/fragment_drawer" />

</android.support.v4.widget.DrawerLayout>

当您在装有Android 7.1的设备上划分屏幕时,如果应用程序是屏幕的第二部分,则可以在顶部看到该间隙。
西塞罗·莫拉

0

试试这个:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer_layout"
android:fitsSystemWindows="true">


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--Main layout and ads-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/ll_main_hero"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">

        </FrameLayout>

        <FrameLayout
            android:id="@+id/ll_ads"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <View
                android:layout_width="320dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                android:background="#ff00ff" />
        </FrameLayout>


    </LinearLayout>

    <!--Toolbar-->
    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/toolbar"
        android:elevation="4dp" />
</FrameLayout>


<!--left-->
<ListView
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@null"
    android:background="@mipmap/layer_image"
    android:id="@+id/left_drawer"></ListView>

<!--right-->
<FrameLayout
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:background="@mipmap/layer_image">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ken2"
        android:scaleType="centerCrop" />
</FrameLayout>

风格:

<style name="ts_theme_overlay" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/red_A700</item>
    <item name="colorPrimaryDark">@color/red1</item>
    <item name="android:windowBackground">@color/blue_A400</item>
</style>

主要活动扩展了ActionBarActivity

toolBar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolBar);

现在,您可以onCreateOptionsMenu像普通的ActionBar一样使用ToolBar。

这是我的布局

  • 顶部:左抽屉-右抽屉
    • MID:工具栏(ActionBar)
    • 底部:ListFragment

希望你能理解!玩得开心!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.