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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26440879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:27:23  来源:igfitidea点击:

How do I use DrawerLayout to display over the ActionBar/Toolbar and under the status bar?

androidnavigation-drawerandroid-appcompat

提问by Chris Banes

I've seen in the new material design Side Nav specthat you can display the drawer over the action bar and behind the status bar. How can I implement this?

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

回答by Chris Banes

New functionality in the framework and support libs allow exactly this. There are three 'pieces of the puzzle':

框架和支持库中的新功能正是允许这样做的。有三块“拼图”:

  1. Using Toolbarso that you can embed your action bar into your view hierarchy.
  2. Making DrawerLayoutfitsSystemWindowsso that it is layed out behind the system bars.
  3. Disabling Theme.Material's normal status bar coloring so that DrawerLayout can draw there instead.
  1. 使用工具栏,以便您可以将操作栏嵌入到视图层次结构中。
  2. 制作DrawerLayoutfitsSystemWindows使其位于系统栏后面。
  3. 禁用Theme.Material的正常状态栏着色,以便 DrawerLayout 可以在那里绘制。

I'll assume that you will use the new appcompat.

我假设您将使用新的 appcompat。

First, your layout should look like this:

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

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

Then in your Activity/Fragment:

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

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

Then you need to make sure that the DrawerLayout is visible behind the status bar. You do that by changing your values-v21 theme:

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

values-v21/themes.xml

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

Note: If a <fragment android:name="fragments.NavigationDrawerFragment">is used instead of

注意:如果使用 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>

the actual layout, the desired effect will be achieved if you call fitsSystemWindows(boolean)on a view that you return from onCreateViewmethod.

在实际布局中,如果调用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;
}

回答by Suyash

EDIT: The new Design Support Library supports this and the previous method is no longer required.

编辑:新的设计支持库支持这一点,不再需要以前的方法。

This can now be achieved using the new Android Design Support Library.

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

You can see the Cheesesquare sample appby Chris Banes which demos all the new features.

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



Previous method:

以前的方法:

Since there is no complete solution posted, here is the way I achieved the desired result.

由于没有发布完整的解决方案,这是我达到预期结果的方式。

First include a ScrimInsetsFrameLayoutin your project.

首先在您的项目中包含一个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);
    }
}

Then create a styleable so that the insetForegroundcan be set.

然后创建一个 styleable 以便insetForeground可以设置。

values/attrs.xml

值/attrs.xml

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

Update your activity's xml file and make sure android:fitsSystemWindowsis set to true on both the DrawerLayoutas well as the ScrimInsetsFrameLayout.

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

layout/activity_main.xml

布局/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>

Inside the onCreate method of your activity set the status bar background color on the drawer layout.

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

MainActivity.java

主活动.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));
}

Finally update your app's theme so that the DrawerLayoutis behind the status bar.

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

values-v21/styles.xml

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

Result:

结果:

回答by reVerse

With the release of the latest Android Support Library (rev 22.2.0)we've got a Design Support Libraryand as part of this a new view called NavigationView. So instead of doing everything on our own with the ScrimInsetsFrameLayoutand all the other stuff we simply use this view and everything is done for us.

随着最新的Android 支持库(修订版 22.2.0)的发布,我们有了一个设计支持库,其中包含一个名为NavigationView的新视图。因此,与其使用ScrimInsetsFrameLayout和所有其他东西我们自己做所有事情,不如简单地使用这个视图,一切都为我们完成。

Example

例子

Step 1

第1步

Add the Design Support Libraryto your build.gradlefile

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

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

Step 2

第2步

Add the NavigationViewto your DrawerLayout:

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

Step 3

第 3 步

Create a new menu-resource in /res/menuand add the items and icons you wanna display:

在其中创建一个新的菜单资源/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>

Step 4

第四步

Init the NavigationView and handle click events:

初始化 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;
            }
        });
    }
}

Step 5

第 5 步

Be sure to set android:windowDrawsSystemBarBackgroundsand android:statusBarColorin values-v21otherwise your Drawer won`t be displayed "under" the StatusBar

一定要设置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>

Optional Step

可选步骤

Add a Header to the NavigationView. For this simply create a new layout and add app:headerLayout="@layout/my_header_layout"to the NavigationView.

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

Result

结果

picture showing navigation view

图片显示导航视图

Notes

笔记

  • The highlighted coloruses the color defined via the colorPrimaryattribute
  • The List Itemsuse the colordefined via the textColorPrimaryattribute
  • The Iconsuse the colordefined via the textColorSecondaryattribute
  • 所述突出颜色使用经由所述定义的颜色colorPrimary属性
  • 列表项使用的颜色通过定义的textColorPrimary属性
  • 图标使用颜色通过定义的textColorSecondary属性

You can also check the example appby Chris Baneswhich highlights the NavigationView along with the other new views that are part of the Design Support Library (like the FloatingActionButton, TextInputLayout, Snackbar, TabLayoutetc.)

您还可以查看Chris Banes示例应用程序,它突出显示了 NavigationView 以及作为设计支持库一部分的其他新视图(如FloatingActionButtonTextInputLayoutSnackbarTabLayout等)

回答by Vipin Sahu

The above all approaches are correct and may be working . I have created a working demo following the above guide and tested on 2.x to 5.x

以上所有方法都是正确的,可能有效。我按照上述指南创建了一个工作演示,并在 2.x 到 5.x 上进行了测试

You can clone from Github

你可以从Github克隆

The important thing to play around is in Main Activity

重要的事情是在主要活动中

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

and the call back

和回电

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

Absolutely the Theme for V21 does the magic

绝对是 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>

and the ScrimInsetsFrameLayout

和 ScrimInsetsFrameLayout

Now this come more easy with new Design Support library

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

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

clone from @Chris Banes https://github.com/chrisbanes/cheesesquare

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

回答by Nicolas Jafelle

Make it work, in values-v21 styles or theme xml needs to use this attribute:

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

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

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

That make the magic!

这使魔法!

回答by Harry Sharma

All answers mentioned here are too old and lengthy.The best and short solution that work with latest Navigationview is

此处提到的所有答案都太旧且冗长。适用于最新 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);

    }
}

this is going to change your status bar color to transparent when you open the drawer

当您打开抽屉时,这会将您的状态栏颜色更改为透明

Now when you close the drawer you need to change status bar color again to dark.So you can do it in this way.

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

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

and then in main layout add a single line i.e

然后在主布局中添加一行,即

            android:fitsSystemWindows="true"

and your drawer layout will look like

你的抽屉布局看起来像

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

and your navigation view will look like

你的导航视图看起来像

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

I have tested it and its fully working.Hope it helps someone.This may not be the best approach but it works smoothly and is simple to implement. Mark it up if it helps.Happy coding :)

我已经测试过它并且它完全正常工作。希望它可以帮助某人。这可能不是最好的方法,但它工作顺利并且易于实施。如果有帮助,请标记它。快乐编码:)

回答by katwal-Dipak

I am Using Design Support Library. And just by using custom theme I achived transparent Status Bar when Opened Navigation Drawer.

我正在使用设计支持库。并且通过使用自定义主题,我在打开导航抽屉时实现了透明的状态栏。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

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

Finally add theme in Manifest File

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

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

Do not forget to use the property, android:fitsSystemWindows="true"in "DrawerLayout"

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

回答by Nicolás López

This is the most simple, and it worked for me:

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

In the values-21:

在值 21 中:

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

In the values:

在价值观中:

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

And set to your toolbar

并设置到您的工具栏

android:layout_marginTop="@dimen/topMargin"

回答by mato

Instead of using the ScrimInsetsFrameLayout... Isn't it easier to just add a view with a fixed height of 24dpand a background of primaryColor?

而不是使用ScrimInsetsFrameLayout... 添加一个固定高度24dp和背景的视图不是更容易primaryColor吗?

I understand that this involves adding a dummy view in the hierarchy, but it seems cleaner to me.

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

I already tried it and it's working well.

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

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

回答by Son Nguyen Thanh

Try with this:

试试这个:

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

风格 :

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

Main Activity extends ActionBarActivity

主 Activity 扩展 ActionBarActivity

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

Now you can onCreateOptionsMenulike as normal ActionBar with ToolBar.

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

This is my Layout

这是我的布局

  • TOP: Left Drawer - Right Drawer
    • MID: ToolBar (ActionBar)
    • BOTTOM: ListFragment
  • 顶部:左抽屉 - 右抽屉
    • MID:工具栏(ActionBar)
    • 底部:列表片段

Hope you understand !have fun !

希望你明白!玩得开心!