Android 4.2中的操作栏图标大小

7
Android 4.2中的操作栏图标大小是否已更改? 我有一个120x48px的HDPI图标,在Android 4.1及以下版本中完美呈现。它仍然是这样的。 然而,在任何4.2设备上,它被压缩为48x48px以适应屏幕。或者类似于那样; 它绝对是一个正方形。 有什么想法吗?谢谢!

5
我遇到了这个同样的问题。我找到了下面这个提交,它添加了这个“功能”:https://github.com/android/platform_frameworks_base/commit/c0047d4e111b8cfbffdbebb55f846c7ae935e53e - Hameno
这是一个很棒的发现,非常感谢!那么我猜我们真的什么也做不了,对吗?或者我错了? - Bogdan Zurac
这有点荒谬。非常感谢你,安卓。 - annie
2个回答

5
这并不理想,但是你似乎可以通过使用自定义动作视图来规避这个限制。
类似于这样的:
```html ```
<?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

我刚学会使用这种方法,所以除了增加的复杂性之外,我还不知道是否存在任何主要的缺点。


2

我找到了一个答案,虽然有点hacky但是有效:

总体思路是监听布局变化并将新的边界应用于可绘制对象。代码大致如下:

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(我建议从中扩展出一个抽象的基础Activity)来处理以下回调函数: onCreate onMenuOpened(如果您延迟调用此函数(例如200ms),则可以提高性能并降低闪烁(绘制内容大小的变化)) onPrepareOptionsMenu(如果您延迟调用此函数(例如200ms),则可以提高性能并降低闪烁(绘制内容大小的变化))
这对我在Android 4.2上的Nexus 7和Nexus 10可行。未来的更新也可能会出现问题,但至少目前似乎可以使用。

获取“actionBarView.getChildAt(i3)”的错误 - i3无法解析为变量。 - Shirish Herwade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接