remove padding around action bar left icon on Android 4.0+

Digging into AOSP sources, it seems the code involved is in com.android.internal.widget.ActionBarView.java. In particular the relevant part is the onLayout() method of the inner class ActionBarView$HomeView, partially reported below (lines 1433-1478):

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        ...
        final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
        final int iconHeight = mIconView.getMeasuredHeight();
        final int iconWidth = mIconView.getMeasuredWidth();
        final int hCenter = (r - l) / 2;
        final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
        final int iconBottom = iconTop + iconHeight;
        final int iconLeft;
        final int iconRight;
        int marginStart = iconLp.getMarginStart();
        final int delta = Math.max(marginStart, hCenter - iconWidth / 2);
        if (isLayoutRtl) {
            iconRight = width - upOffset - delta;
            iconLeft = iconRight - iconWidth;
        } else {
            iconLeft = upOffset + delta;
            iconRight = iconLeft + iconWidth;
        }
        mIconView.layout(iconLeft, iconTop, iconRight, iconBottom);
    }

the same widget use this layout, defined in res/layout/action_bar_home.xml:

<view xmlns:android="http://schemas.android.com/apk/res/android"
  class="com.android.internal.widget.ActionBarView$HomeView"
  android:layout_width="wrap_content"
  android:layout_height="match_parent">
<ImageView android:id="@android:id/up"
           android:src="https://stackoverflow.com/questions/16026007/?android:attr/homeAsUpIndicator"
           android:layout_gravity="center_vertical|start"
           android:visibility="gone"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_marginEnd="-8dip" />
<ImageView android:id="@android:id/home"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_marginEnd="8dip"
           android:layout_marginTop="@android:dimen/action_bar_icon_vertical_padding"
           android:layout_marginBottom="@android:dimen/action_bar_icon_vertical_padding"
           android:layout_gravity="center"
           android:adjustViewBounds="true"
           android:scaleType="fitCenter" />
</view>

According to sources the icon is shown in the Imageview with id=android.R.id.home. The onLayout() method reported above takes account of the ImageView margins defined in the layout, which can’t be set via theme/style override because they use the value @android:dimen/action_bar_icon_vertical_padding.

All you can do is to get rid of those values at runtime, and set them according your needs:
simply retrieve the ImageView and set its top and bottom margins to 0. Something like this:

ImageView icon = (ImageView) findViewById(android.R.id.home);
FrameLayout.LayoutParams iconLp = (FrameLayout.LayoutParams) icon.getLayoutParams();
iconLp.topMargin = iconLp.bottomMargin = 0;
icon.setLayoutParams( iconLp );

EDIT: I’ve just realized I didn’t cover how to get rid of left padding. Solution below.

Left padding on actionbar is affected by the Navigating Up behavior of actionbar icon. When that is disabled (via ActionBar.setDisplayHomeAsUpEnabled(false)) the left/up indicator is gone, but a left padding is used as well. A simple solution:

  1. enable the actionbar up navigation using ActionBar.setDisplayHomeAsUpEnabled(true) in order to consider the indicator view in the layout process
  2. force the drawable used as up indicator in your res/values-v14/styles.xml to null

eg:

<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <!-- API 14 theme customizations can go here. -->
    <item name="android:homeAsUpIndicator">@null</item>
</style>

Leave a Comment