Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Home button in action bar not working in Lollipop

I have a problem, cause I'm developing app for lollipop without support library v7, so I need to use standard ActionBar. Previously I used setHomeButtonEnabled in multiple activities with actionBar.

When I switched app theme to material everything is working fine, except setHomeButtonEnabled method.

Title is not clickable.

Help!

like image 748
TommyNecessary Avatar asked Nov 14 '14 08:11

TommyNecessary


1 Answers

For some reason, someone at Google decided that these should become no-op's. This can be seen below.

ToolbarWidgetWrapper.java

@Override
public void setHomeButtonEnabled(boolean enable) {
    // Ignore
}

ToolbarActionBar.java

@Override
public void setHomeButtonEnabled(boolean enabled) {
    // If the nav button on a Toolbar is present, it's enabled. No-op.
}

It seem's as though ToolbarWidgetWrapper which is used to map the Toolbar to ActionBar differences treats the Nav Icon in the Toolbar as the 'Home As Up Indicator'. So only that part is clickable. The new Logo you can set on Toolbar can never be clickable. They don't even expose the view, its private rolls-eyes.

So the first work around is if you don't use the 'Home As Up' feature or you are willing to combine your up drawable with your home drawable then you could simply set the android:homeAsUpIndicator attribute in your android:actionBarStyle along with android:displayOptions="homeAsUp".

<style name="AppBaseTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBar</item>
</style>

<style name="ActionBar" parent="@android:style/Widget.Material.Light.ActionBar.Solid">
    <item name="android:background">@color/action_bar_bg</item>
    <item name="android:displayOptions">homeAsUp</item>
    <item name="android:homeAsUpIndicator">@drawable/app_logo</item>
</style>

Obviously this same thing can be done with code.

getActionBar().setHomeAsUpIndicator(R.drawable.app_logo);
getActionBar().setDisplayHomeAsUpEnabled(true);

But this means it will not appear whilst the activity is actually loading. So best to go with the theming option.

The 3rd option which would be best is just to style the navigation button for the new Toolbar view. Which uses android:navigationButtonStyle but guess what.. they didn't make that one public. I believe this is a geninue mistake but this is all starting to feel much like the original problems we all had with ActionBar in the first place.

So lets work around, the work around. Ok let's try just setting the android:navigationIcon in the android:toolbarStyle. Nope. Ok lets try all other possible variations you can think of including using android:actionBarStyle and android:actionBarTheme. Nope. This I expect is because the navigationIcon is being overridden some place in the default ActionBar/Activity/Toolbar mess. I can't me bothered to locate where and work a way around it.

Ok, so finally lets choose the most flexible option. Drop the default Home Button and use our own by implementing the older custom navigation feature. This does mean if you already use a custom nav you'll have to combine your nav with this one.

values-v21/styles.xml

<style name="AppBaseTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBar</item>
</style>

<style name="ActionBar" parent="@android:style/Widget.Material.Light.ActionBar.Solid">
    <item name="android:background">@color/action_bar_bg</item>
    <item name="android:displayOptions">showCustom</item>
    <item name="android:customNavigationLayout">@layout/nav_layout</item>
</style>

layout-v21/nav_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/home"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="start|center_vertical"
    android:layout_marginEnd="8dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp"
    android:adjustViewBounds="true"
    android:background="?android:attr/actionBarItemBackground"
    android:contentDescription="@string/ab_home_description"
    android:src="@drawable/app_logo"
    android:scaleType="fitCenter"
    />

In your Activity/BaseActivity class add the following. And this will fake the home button.

@Override
public boolean onPrepareOptionsMenu(final Menu menu)
{
    prepareOptionsMenuLollipop(menu);
    return super.onPrepareOptionsMenu(menu);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void prepareOptionsMenuLollipop(Menu menu)
{
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        final MenuItem homeItem = menu.add(Menu.NONE, android.R.id.home, 
            Menu.NONE, R.string.ab_home_description);
        homeItem.setVisible(false);
        View homeView = getActionBar().getCustomView().findViewById(android.R.id.home);
        homeView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v)
            {
                getWindow().getCallback().onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, homeItem);
            }
        });
    }
}
like image 181
Simon Avatar answered Sep 27 '22 18:09

Simon