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

后端 未结 10 836
[愿得一人]
[愿得一人] 2020-11-22 04:05

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

相关标签:
10条回答
  • 2020-11-22 04:25

    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

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

    Now you can onCreateOptionsMenu like as normal ActionBar with ToolBar.

    This is my Layout

    • TOP: Left Drawer - Right Drawer
      • MID: ToolBar (ActionBar)
      • BOTTOM: ListFragment

    Hope you understand !have fun !

    0 讨论(0)
  • 2020-11-22 04:31

    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

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

    0 讨论(0)
  • 2020-11-22 04:33

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

    Example

    Step 1

    Add the Design Support Library to your build.gradle file

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

    Step 2

    Add the NavigationView to your 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

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

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

    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

    Be sure to set android:windowDrawsSystemBarBackgrounds and android:statusBarColor in values-v21 otherwise your Drawer won`t be displayed "under" the StatusBar

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

    Result

    picture showing navigation view

    Notes

    • The highlighted color uses the color defined via the colorPrimary attribute
    • The List Items use the color defined via the textColorPrimary attribute
    • The Icons use the color defined via the textColorSecondary attribute

    You can also check the example app by Chris Banes which highlights the NavigationView along with the other new views that are part of the Design Support Library (like the FloatingActionButton, TextInputLayout, Snackbar, TabLayout etc.)

    0 讨论(0)
  • 2020-11-22 04:34

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

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

    0 讨论(0)
  • 2020-11-22 04:38

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

    1. Using Toolbar so that you can embed your action bar into your view hierarchy.
    2. Making DrawerLayout fitsSystemWindows so 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.

    I'll assume that you will use the new 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:

    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>
    

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

    <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 onCreateView method.

    @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;
    }
    
    0 讨论(0)
  • 2020-11-22 04:39

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

    In the values-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"
    
    0 讨论(0)
提交回复
热议问题