在使用 Android v7 包的 Toolbar 時,開發者常希望自定義高度以適應設計需求。然而,當修改 Toolbar 高度後,菜單項的圖標往往不再垂直居中,影響視覺效果。默認情況下,Toolbar 高度引用 ?attr/actionBarSize(約 56dp),但許多設計要求更緊湊的高度。
Toolbar 內部佈局對菜單項的垂直居中依賴於固定的高度測量邏輯。當高度改變時,默認的 ActionMenuView 和 ActionMenuItemView 未能正確重新計算垂直偏移,導致圖標偏移。
在 XML 佈局中定義 Toolbar 時,指定固定高度並設置 android:minHeight,同時使用 app:contentInsetStart="0dp" 和 app:contentInsetEnd="0dp" 去除默認內邊距:
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:minHeight="48dp"
android:background="?attr/colorPrimary"
app:contentInsetStart="0dp"
app:contentInsetEnd="0dp"
app:titleTextAppearance="@style/Toolbar.TitleText" />
創建自定義 CenteredActionMenuItemView 繼承 ActionMenuItemView,重寫 onMeasure 和 onDraw 確保圖標垂直居中:
public class CenteredActionMenuItemView extends ActionMenuItemView {
public CenteredActionMenuItemView(Context context) { super(context); }
public CenteredActionMenuItemView(Context context, AttributeSet attrs) { super(context, attrs); }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 強制高度與 Toolbar 一致
int toolbarHeight = getResources().getDimensionPixelSize(R.dimen.custom_toolbar_height);
setMeasuredDimension(getMeasuredWidth(), toolbarHeight);
}
@Override
protected void onDraw(Canvas canvas) {
// 計算圖標垂直居中偏移
Drawable[] drawables = getCompoundDrawables();
if (drawables[0] != null) {
int iconHeight = drawables[0].getIntrinsicHeight();
int paddingTop = (getHeight() - iconHeight) / 2;
setPadding(getPaddingLeft(), paddingTop, getPaddingRight(), getPaddingBottom());
}
super.onDraw(canvas);
}
}
然後在主題中設置 actionMenuItemViewStyle 指向此類。
不使用系統菜單,而是在 Toolbar 中放入自定義 ImageView 或 LinearLayout 作為菜單按鈕,完全掌控佈局:
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="?attr/colorPrimary">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_menu"
android:contentDescription="@string/menu" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
dimens.xml 中定義高度常量,便於全局維護。Toolbar 高度自定義導致菜單圖標不居中,本質是系統默認佈局邏輯與自定義高度不匹配。通過調整內邊距、重寫菜單項視圖或完全自定義佈局,均可完美解決。建議根據項目複雜度選擇最適合的方案。