2012-10-17 13 views
11

に残されています。私は彼らを左に揃えて欲しい。Androidの整列メニュー項目は、私はアクションバーの右側に並んでいる私の<code>res/menu/activity_main.xml</code></p> <p>マイメニュー項目に定義されたメニュー項目を表示する私のアプリケーションでアクションバーを持つアクションバー

のみのソリューション私はこの1つのように、この使用されるカスタムアクションバーが見つかり:しかし Positioning menu items to the left of the ActionBar in Honeycomb

私は私のメニューのためのカスタムレイアウトを作成したいいけません。私はres/menu/activity_main.xmlから生成されたデフォルトのメニュー項目を使いたいです。

これは可能ですか?

+4

スプリットアクションバーを調べることができます。 Androidユーザーは、右のActionBarアイコン、または画面の下部にある分割バーに精通しています。 Androidユーザーが既に使い慣れていて快適なものを再設計することは望ましくありません。 http://developer.android.com/guide/topics/ui/actionbar.html#SplitBar – Sababado

+1

この投稿を確認してください。それはあなたを助けるはずです。 http://stackoverflow.com/questions/7454102/how-to-align-items-in-action-bar-to-the-left – pepyakin

+0

私はdownvotesを取得しないでください。回答がNOの場合は質問が間違っていることを意味します。 – hendrix

答えて

0

あなたはこのようにそれを行うことができます。

activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 
      ActionBar.DISPLAY_SHOW_CUSTOM); 
activity.getActionBar().setCustomView(mAutoSyncSwitch, new ActionBar.LayoutParams(
      ActionBar.LayoutParams.WRAP_CONTENT, 
      ActionBar.LayoutParams.WRAP_CONTENT, 
      Gravity.CENTER_VERTICAL | Gravity.LEFT)); 
+11

私はspecificaly(太字)を言ったアクションバーにカスタムビューを表示したくない... – hendrix

+0

カスタムレイアウトではなく、レイアウトパラメータを既存のレイアウトに追加するだけで、何も変更されません。しかし、そうしなければカスタムレイアウトを書く必要があります。そうしなければ、彼はレイアウトを編集することができなくなるからです。 –

+2

アクションバーのレイアウトを編集せずに実際に行う必要がある場合は、それを行うことはできません。 –

3

さて、私はこのことについて興味があったので、私はSDKのソースの奥深くに掘りました。私はそれのXMLファイルで3メニュー項目にAppCompatActivityを使用し、私はデフォルトにこのでしたonCreateOptionMenu方法、使用:私はデバッガでインフレート法から上に移動した後

@Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

を、私は、次のスタックを行ってきました:

updateMenuView():96, BaseMenuPresenter (android.support.v7.internal.view.menu) 
updateMenuView():231, ActionMenuPresenter (android.support.v7.widget) 
dispatchPresenterUpdate():284, MenuBuilder (android.support.v7.internal.view.menu) 
onItemsChanged():1030, MenuBuilder (android.support.v7.internal.view.menu) 
startDispatchingItemsChanged():1053, MenuBuilder (android.support.v7.internal.view.menu) 
preparePanel():1303, AppCompatDelegateImplV7 (android.support.v7.app) 
doInvalidatePanelMenu():1541, AppCompatDelegateImplV7 (android.support.v7.app) 
access$100():92, AppCompatDelegateImplV7 (android.support.v7.app) 
run():130, AppCompatDelegateImplV7$1 (android.support.v7.app) 
handleCallback():739, Handler (android.os) 
dispatchMessage():95, Handler (android.os) 
loop():148, Looper (android.os) 
main():5417, ActivityThread (android.app) 
invoke():-1, Method (java.lang.reflect) 
run():726, ZygoteInit$MethodAndArgsCaller (com.android.internal.os) 
main():616, ZygoteInit (com.android.internal.os) 

それはrevelant作業が行われる場合、これは、BaseMenuPresenterupdateMenuView方法に終わりました。

メソッドのコード:ここで

public void updateMenuView(boolean cleared) { 
     final ViewGroup parent = (ViewGroup) mMenuView; 
     if (parent == null) return; 

     int childIndex = 0; 
     if (mMenu != null) { 
      mMenu.flagActionItems(); 
      ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); 
      final int itemCount = visibleItems.size(); 
      for (int i = 0; i < itemCount; i++) { 
       MenuItemImpl item = visibleItems.get(i); 
       if (shouldIncludeItem(childIndex, item)) { 
        final View convertView = parent.getChildAt(childIndex); 
        final MenuItemImpl oldItem = convertView instanceof MenuView.ItemView ? 
          ((MenuView.ItemView) convertView).getItemData() : null; 
        final View itemView = getItemView(item, convertView, parent); 
        if (item != oldItem) { 
         // Don't let old states linger with new data. 
         itemView.setPressed(false); 
         ViewCompat.jumpDrawablesToCurrentState(itemView); 
        } 
        if (itemView != convertView) { 
         addItemView(itemView, childIndex); 
        } 
        childIndex++; 
       } 
      } 
     } 

     // Remove leftover views. 
     while (childIndex < parent.getChildCount()) { 
      if (!filterLeftoverView(parent, childIndex)) { 
       childIndex++; 
      } 
     } 
    } 

getItemViewaddItemView方法は、彼らの名は言って何をすべきか。最初は新しいビューを展開し、2番目は新しいビューを親に追加します。さらに重要なのは、デバッガの下で、親オブジェクトをチェックすることができます。ActionMenuViewで、LinearLayoutから継承され、フォームがabc_action_menu_layout.xmlになります。

これは、このビューを取得できる場合は、あなたが望むことができることを意味します。理論的には、それは多くの反省を伴って行うことができると思いますが、それは痛いでしょう。 代わりに、コード内でそれを再現することができます。実装はhereです。

上記のことによると、あなたの質問の回答はYESですが、それは難しいでしょう。

編集:

私は反射でこれを行うためのコンセプトの証明を作成しました。私はcom.android.support:appcompat-v7:23.1.0を使用しました。

私はこれをエミュレータ(Android 6.0)とZuk Z1(CM Android 5.1.1)で試しましたが、どちらもうまくいきます。

メニューXML:

<menu xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <item android:id="@+id/action_settings" android:title="@string/action_settings" 
     android:orderInCategory="100" app:showAsAction="always" /> 
    <item android:id="@+id/action_settings2" android:title="TEST1" 
     android:orderInCategory="100" app:showAsAction="always" /> 
    <item android:id="@+id/action_settings3" android:title="TEST2" 
     android:orderInCategory="100" app:showAsAction="always" /> 
</menu> 

Activty XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="New Button" 
     android:id="@+id/button" 
     android:layout_gravity="center_vertical" /> 
</LinearLayout> 

活動:

public class Main2Activity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //only a linear layout with one button 
     setContentView(R.layout.activity_main2); 

     Button b = (Button) findViewById(R.id.button); 

     // do the whole process for a click, everything is inited so we dont run into NPE 
     b.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       AppCompatDelegate delegate = getDelegate(); 

       Class delegateImpClass = null; 
       Field menu = null; 
       Method[] methods = null; 

       try { 

        //get objects based on the stack trace 
        delegateImpClass = Class.forName("android.support.v7.app.AppCompatDelegateImplV7"); 

        //get delegate->mPreparedPanel 
        Field mPreparedPanelField = delegateImpClass.getDeclaredField("mPreparedPanel"); 
        mPreparedPanelField.setAccessible(true); 
        Object mPreparedPanelObject = mPreparedPanelField.get(delegate); 

        //get delegate->mPreparedPanel->menu 
        Class PanelFeatureStateClass = Class.forName("android.support.v7.app.AppCompatDelegateImplV7$PanelFeatureState"); 
        Field menuField = PanelFeatureStateClass.getDeclaredField("menu"); 
        menuField.setAccessible(true); 
        Object menuObjectRaw = menuField.get(mPreparedPanelObject); 
        MenuBuilder menuObject = (MenuBuilder) menuObjectRaw; 

        //get delegate->mPreparedPanel->menu->mPresenter(0) 
        Field mPresentersField = menuObject.getClass().getDeclaredField("mPresenters"); 
        mPresentersField.setAccessible(true); 
        CopyOnWriteArrayList<WeakReference<MenuPresenter>> mPresenters = (CopyOnWriteArrayList<WeakReference<MenuPresenter>>) mPresentersField.get(menuObject); 
        ActionMenuPresenter presenter0 = (ActionMenuPresenter) mPresenters.get(0).get(); 

        //get the view from the presenter 
        Field mMenuViewField = presenter0.getClass().getSuperclass().getDeclaredField("mMenuView"); 
        mMenuViewField.setAccessible(true); 
        MenuView menuView = (MenuView) mMenuViewField.get(presenter0); 
        ViewGroup menuViewParentObject = (ViewGroup) ((View) menuView); 

        //check the menu items count 
        int a = menuViewParentObject.getChildCount(); 
        Log.i("ChildNum", a + ""); 




        //set params as you want 
        Toolbar.LayoutParams params = (Toolbar.LayoutParams) menuViewParentObject.getLayoutParams(); 

        params.gravity = Gravity.LEFT; 

        menuViewParentObject.setLayoutParams(params); 




       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } catch (NoSuchFieldException e) { 
        e.printStackTrace(); 
       } catch (IllegalAccessException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 
} 

は、重力が、ここでは変更されているが、これはどのrevelantことはありません画面に差。実際の目に見える変化を得るには、他のレイアウトパラメータ(例えば幅)を調整する必要があります。

すべてでは、カスタムレイアウトを使用する方がずっと簡単です。

関連する問題