Android 4.2中的操作栏图标大小有变化吗?我有一个120x48px的HDPI图标,它在Android4.1和更低版本中渲染得很好。它现在仍然是。
然而,在任何4.2版本的设备上,从我所能看到的来看,它被静音到了48x48px。或者类似的东西;它绝对是一个正方形。
有什么想法吗?谢谢!
发布于 2013-01-01 16:50:20
所以,我找到了一个答案,它有点老生常谈,但有效(TM):
一般的想法是监听布局的变化,并将新的边界应用于可绘制的内容。这可能如下所示:
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 (我发现如果你称之为延迟(例如200ms),它将提高性能并减少闪烁(绘图文件的大小变化)) onPrepareOptionsMenu (我发现如果称为延迟(例如200ms),它将提高性能并减少闪烁(绘图文件的大小变化))
这在安装了Android 4.2的Nexus 7和Nexus 10上适用。你可以预期它会在未来的更新中失败,但至少现在它看起来是有效的。
发布于 2013-01-16 02:47:32
这并不理想,但似乎可以通过使用自定义操作视图来绕过此限制。
如下所示:
<?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。
您必须在OnCreateOptionsMenu方法中绑定单击侦听器。这里有一个半途而废的例子:http://developer.android.com/guide/topics/ui/actionbar.html#ActionView。
我只是刚刚学会使用这种方法,所以我还不知道除了增加的复杂性之外,是否还有任何重大的缺点。
https://stackoverflow.com/questions/13519710
复制