Question

Background:

I currently enable the HomeUp button on Activity, thanks to:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);  

According to the Documentation, it's related to setHomeButtonEnabled which:

Enables or disables the "home" button in the corner of the action bar [...] Setting the constant DISPLAY_HOME_AS_UP display option (setDisplayHomeAsUpEnabled method) will automatically enable the home button.

Also, I customize with a selector the state background of items in ActionBar with this style:

<style name="MainTheme" parent="@style/Theme.AppCompat.Light">
    <item name="android:actionBarItemBackground">@drawable/ab_item_background</item>
    <item name="actionBarItemBackground">@drawable/ab_item_background</item>
</style>

Although this works well, I don't want to use a drawable selector for the HomeUp button when UpIndicator is enabled.

Why do I need it:

The ActionBar's background is grey (relative to Theme.AppCompat.Light) and the selector uses a green background when items are pressed. However, the app icon is also green which, when it is pressed, merges with the background pressed state. I need to avoid this by not using a drawable for HomeUp's background.

Question:

How can I achieve this, any idea about a workaround?

Notes:

  1. I tried to search a related attribute, which allows to use a custom background for the app icon and UpIndicator, to customize in style.xml but I didn't find it in the Resources.

  2. If I use setDisplayHomeAsUpEnabled(true) and setDisplayHomeAsUpEnabled(false), I have the expected behaviour for the Menu Items (backgrounds changed relative to its states) but the HomeUp button, although I have the right behaviour with its background, is no longer enabled.

  3. Also, I want to avoid using a CustomView to the ActionBar.


Update:

According to Adneal's answer and after tests and researches, here is the results:

 _______________________________________________________________________________
|     |                        |                         |                      |
| API |       R.id.home        |    android.R.id.home    |        method        |
|_____|________________________|_________________________|______________________|
|     |                        |                         |                      |
|  8  |          OK            |           --            |    getParent() x 1   |
| 10  |          OK            |           --            |    getParent() x 1   |
| 11  |          OK            |           --            |    getParent() x 1   |
| 12  |          OK            |           --            |    getParent() x 1   |
| 13  |          OK            |           --            |    getParent() x 1   |
| 14  |          --            |           OK            |    getParent() x 1   |
| 15  |          --            |           OK            |    getParent() x 1   |
| 16  |          --            |           OK            |    getParent() x 1   |
| 17  |          --            |           OK            |    getParent() x 2   |
| 18  |          --            |           OK            |    getParent() x 2   |
| 19  |          --            |           OK            |    getParent() x 2   |
|_____|________________________|_________________________|______________________|

Then, the right condition should be:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    // retrieve the two parents with "android.R.id.home"
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
    // retrieve the first parent with "android.R.id.home"
} else {
    // retrieve the first parent with "R.id.home"
}
Was it helpful?

Solution

You can set the background of the home button to null by using View.getParent.

This is the layout that contains the home button, once inflated in ActionBarView, is added to the up container layout which is what actually uses the actionBarItemBackground attribute.

However, AppCompat doesn't utilize an "up container" layout, as well as the normal ActionBar up to API level 18 (Jelly Bean MR2).

So, to change the home button background you'd make one call to View.getParent when using the support library or API levels 11-17's ActionBar, but two when you're changing API level 18+'s.

    View home;
    final int version = Build.VERSION.SDK_INT;
    if (version >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        // Normal action bar, post-"up container"
        home = (View) findViewById(android.R.id.home).getParent().getParent();
    } else if (version >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        // Normal action bar, pre-"up container"
        home = (View) findViewById(android.R.id.home).getParent();
    } else {
        // Support library action bar
        home = (View) findViewById(R.id.home).getParent();
    }
    home.setBackgroundDrawable(null);

AppCompat could be updated in the future to include to an "up container" layout, so bear in mind you may need to adjust your code later on to accommodate for that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top