Android 4.2中的操作栏图标大小

Android 4.2中的操作栏图标大小是否更改? 我有一个120x48px的HDPI图标,在Android 4.1及以下版本中完美呈现。 它仍然是。

但是,在任何4.2设备上,它都被压制成适合我所能看到的48×48像素。 或类似的东西; 这绝对是一个广场。

有任何想法吗 ? 谢谢 !

Solutions Collecting From Web of "Android 4.2中的操作栏图标大小"

所以,我find了一个答案,这是有点hacky,但工程(TM):

总体思路是听取布局的变化,并将新的边界应用到drawable。 这可能是这样的:

public static void updateActionBar(final Activity activity) { if (Build.VERSION.SDK_INT >= 17) { try { final View content = activity.findViewById(android.R.id.content); if (content instanceof FrameLayout) { final FrameLayout contentFrameLayout = (FrameLayout) content; final ViewParent parent = contentFrameLayout.getParent(); if (parent instanceof LinearLayout) { final LinearLayout parentLinearLayout = (LinearLayout) parent; final Class<?> actionBarContainerClass = Class.forName("com.android.internal.widget.ActionBarContainer"); final Class<?> actionBarViewClass = Class.forName("com.android.internal.widget.ActionBarView"); final Class<?> actionMenuViewClass = Class.forName("com.android.internal.view.menu.ActionMenuView"); final Class<?> actionMenuItemViewClass = Class.forName("com.android.internal.view.menu.ActionMenuItemView"); for (int i = 0, childCount = parentLinearLayout.getChildCount(); i < childCount; i++) { final View parentLinearLayoutChild = parentLinearLayout.getChildAt(i); handleParentLinearLayoutChild(actionBarContainerClass, actionBarViewClass, actionMenuViewClass, actionMenuItemViewClass, parentLinearLayoutChild); } } } } catch (Exception e) { // Handle or ignore } } } private static void handleParentLinearLayoutChild(final Class<?> actionBarContainerClass, final Class<?> actionBarViewClass, final Class<?> actionMenuViewClass, final Class<?> actionMenuItemViewClass, final View parentLinearLayoutChild) { if (parentLinearLayoutChild instanceof FrameLayout && parentLinearLayoutChild.getClass().equals(actionBarContainerClass)) { final FrameLayout actionBarContainer = (FrameLayout) parentLinearLayoutChild; for (int i = 0, actionBarContainerChildCount = actionBarContainer.getChildCount(); i < actionBarContainerChildCount; i++) { final View actionBarContainerChild = actionBarContainer.getChildAt(i); handleActionBarContainerChild(actionBarViewClass, actionMenuViewClass, actionMenuItemViewClass, actionBarContainerChild); } } } private static void handleActionBarContainerChild(final Class<?> actionBarViewClass, final Class<?> actionMenuViewClass, final Class<?> actionMenuItemViewClass, final View actionBarContainerChild) { if (actionBarContainerChild instanceof ViewGroup && actionBarContainerChild.getClass().equals(actionBarViewClass)) { final ViewGroup actionBarView = (ViewGroup) actionBarContainerChild; actionBarView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { @Override public void onChildViewAdded(final View parent, final View child) { handleActionBarViewChild(child, actionMenuViewClass, actionMenuItemViewClass); } @Override public void onChildViewRemoved(final View parent, final View child) { } }); for (int i = 0, actionBarViewCount = actionBarView.getChildCount(); i < actionBarViewCount; i++) { handleActionBarViewChild(actionBarView.getChildAt(i3), actionMenuViewClass, actionMenuItemViewClass); } } } private static void handleActionBarViewChild(final View child, final Class<?> actionMenuViewClass, final Class<?> actionMenuItemViewClass) { try { if (child instanceof LinearLayout && child.getClass().equals(actionMenuViewClass)) { final LinearLayout actionMenuView = (LinearLayout) child; actionMenuView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { @Override public void onChildViewAdded(final View parent, final View child) { handleActionMenuViewChild(child, actionMenuItemViewClass); } @Override public void onChildViewRemoved(final View parent, final View child) { } }); for (int i = 0, actionMenuViewCount = actionMenuView.getChildCount(); i < actionMenuViewCount; i++) { handleActionMenuViewChild(actionMenuView.getChildAt(i), actionMenuItemViewClass); } } } catch (Exception e) { // Handle or ignore } } private static void handleActionMenuViewChild(final View child, final Class<?> actionMenuItemViewClass) { try { if (child instanceof TextView && child.getClass().equals(actionMenuItemViewClass)) { final TextView menuViewChild = (TextView) child; final Drawable[] compoundDrawables = menuViewChild.getCompoundDrawables(); final Drawable leftDrawable = compoundDrawables[0]; final int intrinsicWidth = leftDrawable.getIntrinsicWidth(); final int intrinsicHeight = leftDrawable.getIntrinsicHeight(); leftDrawable.setBounds(0, 0, intrinsicWidth , intrinsicHeight ); menuViewChild.setCompoundDrawables(leftDrawable, null, null, null); menuViewChild.setPadding(menuViewChild.getPaddingLeft(), 0, menuViewChild.getPaddingRight(), 0); menuViewChild.invalidate(); menuViewChild.requestLayout(); } } catch (Exception e) { // Handle or ignore } } 

然后你必须在每个Activity中调用updateActionBar(我build议在下面的callback中做一个抽象的基本活动):onCreate onMenuOpened(我发现如果你打电话,它会提高性能并减less闪烁(drawable的大小变化)这延迟(例如200毫秒))onPrepareOptionsMenu(我发现,如果你把这个延迟(例如200毫秒),它会提高性能和减less闪烁(drawables的大小变化))

这适用于我在Nexus 7和Nexus 10与Android 4.2。 你可以期待它会失败,未来的更新,但至less现在看起来工作。

这并不理想,但似乎可以通过使用自定义操作视图来解决此限制。

像这样的东西:

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/log_in" android:title="Login" android:showAsAction="always" android:actionLayout="@layout/log_in_button"/> </menu> 

其中@ layout / log_in_button指向一个包含ImageButton的布局文件,其图标设置为src。

您必须绑定OnCreateOptionsMenu方法中的点击侦听器。 这里有一个很好的例子: http : //developer.android.com/guide/topics/ui/actionbar.html#ActionView 。

我只是学会了使用这种方法,所以除了复杂性的增加之外,还不知道是否有重大的缺陷。