Android Navigation Drawer and windowActionBarOverlay = true

前端 未结 5 1600
清酒与你
清酒与你 2021-01-30 14:30

I\'m trying to implement the new Android Navigation Drawer in my application. I have created a BaseActivity.java that handles the Drawer setup and listeners, and I have two suba

相关标签:
5条回答
  • 2021-01-30 14:43

    I have created a working demo following the above guide and tested on 2.x to 5.x

    You can clone from 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

     <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>
    
    0 讨论(0)
  • 2021-01-30 14:45

    You can set a margin at the top of your layout, so that the content draws itself below the ActionBar.

    Just add this in your parent layout:

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

    The attribute actionBarSize refers to, like you would have already guessed, to the size of the ActionBar. You can't set an absolute value as a margin, since the ActionBar does not always have the same size across all Android devices (It's bigger on tablets, smaller on handset devices).

    Edit:

    Set the margin to the 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>
    

    The Google Music app does the same:

    enter image description here

    0 讨论(0)
  • 2021-01-30 14:50

    I solved this problem using 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>
    

    Hope that helps

    0 讨论(0)
  • 2021-01-30 14:51

    And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.

    If you set your ListView gravity to start|bottom it solves your problem. No additional margin is added at the bottom. Looks like the DrawerLayout default gravity is 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"/>
    
    0 讨论(0)
  • 2021-01-30 14:55

    In case anyone is interested in another take to this question. Here's what happened.

    I tried setting only the margin to the top of the list view like this:

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

    But as mentioned on the edited question, that had a weird behaviour where there was also a margin on the bottom despite not being set on the layout resource file.

    So, I was looking closely at the Play Music App and noticed that it's not actually a margin, but rather some padding, and additionally they are using a custom background that fills the space specified by the padding with a transparent color.

    Here's what I did:

    • Set Padding at the top of the ListView, rather than margin:

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

    As said before, it's important to not hard code the dimensions as they vary per device.

    • Create a custom drawable that has a top part transparent, and then rest of a solid color:

    It looks somehow like this:

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

    Note that I tried to use ?android:attr/actionBarSize on the drawable, but that made the app force close. Instead, I searched through grepcode and found a few dimen files with different sizes for the action bar, so I added those to my own project's dimen files.

    • For values: 48dp
    • For values-land: 40dp
    • For values-sw600dp: 56dp

    And after that, I think I looks great, notice on the screenshot how the listview and the actionbar don't overlap, and the transparent part of the listview is just the right size.

    enter image description here

    Hope that helps anyone who was wondering how to achieve this.

    0 讨论(0)
提交回复
热议问题