Asked  7 Months ago    Answers:  5   Viewed   76 times

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?

 Answers

68

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;
}
Tuesday, June 1, 2021
 
CBroe
answered 7 Months ago
56

The CustomView API demo shows how to retrieve styled attributes. The code for the view is here:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/src/com/example/android/apis/view/LabelView.java

The styleable array used to retrieve the text, color, and size is defined in the <declare-styleable> section here:

https://github.com/android/platform_development/blob/master/samples/ApiDemos/res/values/attrs.xml#L24

You can use <declare-styleable> to define any list of attributes that you want to retrieve as a group, containing both your own and ones defined by the platform.

As far as these things being in the documentation, there is a lot of java doc around the styleable arrays that makes them useful to have in the documentation, so they have been left there. However as the arrays change, such as new attributes being added, the values of the constants can change, so the platform ones can not be in the SDK (and please do not use any tricks to try to access them). There should be no need to use the platform ones anyway, because they are each there just for the implementation of parts of the framework, and it is trivial to create your own as shown here.

Sunday, August 8, 2021
 
Precastic
answered 4 Months ago
62

From the docs:

To allow Up navigation with the app icon in the action bar, call setDisplayHomeAsUpEnabled():

@Override public void onCreate(Bundle savedInstanceState) {
     ...
     getActionBar().setDisplayHomeAsUpEnabled(true); }

This adds a left-facing caret alongside the app icon and enables it as an action button such that when the user presses it, your activity receives a call to onOptionsItemSelected(). The ID for the action is android.R.id.home.

This means that you will have to implement your back routine on onOptionsItemSelected and check for R.id.home. To avoid calling the routine when you click on the hamburger menu check for canback too on onOptionsItemSelected.

http://developer.android.com/training/implementing-navigation/ancestral.html#up

EDIT

To archieve what you want you will have to implement your own navigation routine.

    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(shouldBack()) {
               //call onbackpressed or something
                if(displayBackAgain)
                    return; //return after so you don't call syncState();       
            }else if (mNavigationDrawerFragment.isDrawerOpen())
                mNavigationDrawerFragment.closeDrawer();
            else
                mNavigationDrawerFragment.openDrawer();
            mNavigationDrawerFragment.getActionBarDrawerToggle().syncState();
        }
    });
}

To enable the backbutton icon just call getSupportActionBar().setDisplayHomeAsUpEnabled(true); to disable it just call mNavigationDrawerFragment.getActionBarDrawerToggle().syncState();

Saturday, August 14, 2021
 
Freddie
answered 4 Months ago
59

Ok, so I assume that you're already able to monitor your client/server traffic. What you want to do is set a breakpoint on the response then fiddle with it before sending it on to the client.

Here are a couple of different ways to do that:

  1. Rules > Automatic Breakpoints > After Responses
  2. In the quickexec box (the black box at the bottom) type "bpafter yourpage.svc". Now Fiddler will stop at a breakpoint before all requests to any URL that contains "yourpage.svc". Type "bpafter" with no parameters to clear the breakpoint.
  3. Programmatically tamper with the response using FiddlerScript. The best documentation for FiddlerScript is on the official site: http://www.fiddler2.com/Fiddler/dev/

Once you've got a response stopped at the breakpoint, just double click it to open it in the inspectors. You've got a couple of options now:

  1. Right next to the green Run to Completion button (which you click to send the response) there's a dropdown that lets you choose some default response types.
  2. Or, on the Headers inspector, change the response code & message in the textbox at the top.
  3. Or, click the "Raw" inspector and mess with the raw response to do arbitrary things to it. Also a good way to see what your client does when it gets a malformed response, which you'll probably test accidentally :)
Saturday, September 4, 2021
 
Craig Ringer
answered 3 Months ago
43

This is a common issue becoming less apparent when testing on Lollipop or later.

When using standard layouts (such as FrameLayout, RelativeLayout etc.) the default behavior is that child views get drawn in order they are added or inflated.

The fix would look similar to this:

<FrameLayout>
     <!-- Content will be drawn first - below the toolbar. -->
     <FrameLayout android:id="@+id/main_content" />
     <!-- Toolbar will be drawn next - above the content. -->
     <android.support.v7.widget.Toolbar android:id="@+id/toolbar" />
</FrameLayout>

However since Lollipop the android:elevation attribute can override this behavior. Since elevation defines precise position along the Z axis views with higher elevation values will be drawn above those with lower elevation values.

Tuesday, October 19, 2021
 
Reid
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share