Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
656 views
in Technique[技术] by (71.8m points)

remove padding around action bar left icon on Android 4.0+

I want to remove the padding around the icon on the left in the standard android 4.0+ action bar. I'm setting the icon with:

getActionBar().setIcon(getResources().getDrawable(R.drawable.ic_action_myapp));

And I would like the icon to fill vertically the space, touching both top and bottom, similar to what soundcloud app does:

image

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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="?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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...