在安卓4.2操作栏图标的大小图标、大小、操作

2023-09-12 01:38:23 作者:老美女

的操作栏图标大小的Andr​​oid 4.2改变了吗? 我已经被在安卓4.1及以下的完美呈现一个120x48px华电国际的图标。它仍然是。

Has the action bar icon size changed in Android 4.2 ? I've had a 120x48px HDPI icon that was rendered perfectly in Android 4.1 and below. It still is.

然而,在任何4.2的设备,它被压制,以适应为48x48px从我所看到的。或类似的东西;这绝对是一个正方形。

However, on any 4.2 device, it is squelched to fit as 48x48px from what I can see. Or something like that; it's definitely a square.

任何想法?谢谢!

推荐答案

于是,我找到了答案,它有点哈克,但工程(TM):

So, I found an answer, it's kinda hacky but works (TM):

的总体思路是,以监听布局的变化和应用新边界的可绘制。这可能是这样的:

The general idea is to listen for the layout changes and apply new bounds to the drawables. This could look like this:

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
        }
    }

您接下来要调用updateActionBar在每一个活动(我建议作出的抽象基活动从中延伸)以下回调: 的onCreate onMenuOpened(我发现,它会提高性能并降低闪烁(在可绘制的大小的变化),如果你把这种延迟(如200毫秒)) 在prepareOptionsMenu(我发现,它会提高性能并降低闪烁(在可绘制的大小的变化),如果你把这种延迟(如200毫秒))

You then have to call updateActionBar in every Activity (I suggest making an abstract base activity from which you extend) in the following callbacks: onCreate onMenuOpened (I found that it would improve performance and reduce flickering (size changes of the drawables) if you call this delayed (e.g. 200ms)) onPrepareOptionsMenu (I found that it would improve performance and reduce flickering (size changes of the drawables) if you call this delayed (e.g. 200ms))

这对我的作品在Nexus 7和Nexus 10与Android 4.2。你可以期望它失败,未来的更新,但至少从目前来看,它似乎工作。

This works for me on Nexus 7 and Nexus 10 with Android 4.2. You can expect it to fail with future updates but at least for now it seems to work.