2012-11-22 9 views
7

Android 4.2ではアクションバーアイコンのサイズが変更されていますか? Android 4.1以降で完全にレンダリングされた120x48px HDPIアイコンがありました。まだあります。Android 4.2のアクションバーアイコンサイズ4.2

しかし、4.2デバイスでは、私が見ることのできる48x48pxに収まるようにスケルチされています。またはそれのようなもの。間違いなく正方形です。

アイデア?ありがとう!

+5

私はこの非常に同じ問題を偶然見つけました。私はこの "機能"を追加した次のコミットを見つけました:https://github.com/android/platform_frameworks_base/commit/c0047d4e111b8cfbffdbebb55f846c7ae935e53e – Hameno

+0

これはすばらしい発見です、ありがとうございます!だから、私たちは本当に何もできないと思いますよね?または私は間違っていますか? –

+0

これはちょっとばかげています。ありがとうAndroid多くの。 – annie

答えて

2

だから、私は答えを見つけ、それは(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)を呼び出すとパフォーマンスが改善され、ちらつき(drawablesのサイズ変更)が軽減される onPrepareOptionsMenu(パフォーマンスを向上させ、ちらつきを減らすことが判明しました。 ))

これは、Nexus 7とNexus 10 with Android 4.2で動作します。あなたは将来の更新で失敗すると予想できますが、少なくとも今のところはうまくいくようです。

+0

ああ!コードをありがとう。 – annie

+0

"actionBarView.getChildAt(i3)"でエラーが発生する - i3を変数に解決できません –

5

これは理想的ではありませんが、この制限を回避するには、カスタムアクションビューを使用することができます。 SRCとして設定し、あなたのアイコンでのImageButtonを含むレイアウトファイルへ

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

@レイアウト/ log_in_buttonポイント:

このような何かを。

OnCreateOptionsMenuメソッドでクリックリスナーをバインドする必要があります。ここには良い例の半分があります:http://developer.android.com/guide/topics/ui/actionbar.html#ActionView

私はこのメソッドを使用することを学んだだけなので、複雑さが増していることに加えて大きな落とし穴があるかどうかはまだ分かりません。