web-dev-qa-db-ja.com

ツールバーの等間隔のメニュー項目

だから私は私のアクティビティにAndroid.support.v7.widget.Toolbarを実装して、以前サポートされていた分割ActionBarに似せるようにしています。

これが私のツールバーのXMLです。

<Android.support.v7.widget.Toolbar
    Android:id="@+id/toolbar_btm"
    Android:layout_height="wrap_content"
    Android:layout_width="match_parent"
    Android:minHeight="?attr/actionBarSize"
    Android:background="@color/toolbar_bkgnd"
    Android:layout_alignParentBottom="true"
    app:theme="@style/ToolBarTheme" />

使用しているツールバーのスタイルは次のとおりです。

<style name="ToolBarTheme" parent="Theme.AppCompat">
    <item name="actionButtonStyle">@style/ActionButtonStyle</item>
    <item name="Android:actionButtonStyle">@style/ActionButtonStyle</item>
    <item name="Android:textColor">@Android:color/white</item>
</style>

ツールバーメニューボタンのスタイル。最初の計画は、画面サイズに基づいてminWidthを計算し、各メニューボタンに設定することでした。

<style name="ActionButtonStyle" parent="@Android:style/Widget.Holo.Light.ActionButton">
    <item name="Android:minWidth">56dip</item>
    <item name="Android:paddingLeft">0dip</item>
    <item name="Android:paddingRight">0dip</item>
</style>

そして最後に、これが私の活動で呼んでいるものです。

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_btm);
toolbarBtm.inflateMenu(R.id.menu);

問題は、下部のメニュー項目Toolbarが次のように右揃えされていることです。 Right aligned menu items

ただし、次のように均等に配置する必要があります。

Evenly spaced menu items

21
MrEngineer13

ここにあります 私にとって何がうまくいったか*:

EnhancedMenuInflater.Java

import Android.support.v4.internal.view.SupportMenuItem;
import Android.support.v7.internal.view.menu.MenuItemImpl;
import Android.view.Menu;
import Android.view.MenuInflater;
import Android.view.MenuItem;

import here.is.your.R;

public class EnhancedMenuInflater {

    public static void inflate(MenuInflater inflater, Menu menu, boolean forceVisible) {
        inflater.inflate(R.menu.menu, menu);

        if (!forceVisible) {
            return;
        }

        int size = menu.size();
        for (int i = 0; i < size; i++) {
            MenuItem item = menu.getItem(i);
            // check if app:showAsAction = "ifRoom"
            if (((MenuItemImpl) item).requestsActionButton()) {
                item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS);
            }
        }
    }
}

MainActivity.Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (toolbar == null) {
        EnhancedMenuInflater.inflate(getMenuInflater(), menu, false);
    }
    return super.onCreateOptionsMenu(menu);
}

// somewhere after views have been set.
if (toolbar != null) {
    EnhancedMenuInflater.inflate(getMenuInflater(), toolbar.getMenu(), true);
    toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            return onOptionsItemSelected(item);
        }
    });
}

SplitToolbar.Java

import Android.content.Context;
import Android.support.v7.widget.ActionMenuView;
import Android.support.v7.widget.Toolbar;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;

public class SplitToolbar extends Toolbar {
    public SplitToolbar(Context context) {
        super(context);
    }

    public SplitToolbar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SplitToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        if (child instanceof ActionMenuView) {
            params.width = LayoutParams.MATCH_PARENT;
        }
        super.addView(child, params);
    }
}

Layout.xml

<here.is.my.SplitToolbar
    Android:id="@+id/toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignParentBottom="true"/>

私が働いたと言うとき、それはそれが私のメニュー、テキスト、および画像のすべての中心にあることを意味します。メニューにアイコンのみを使用すると、見栄えがよくなります。私はまだそれらを中央に配置し、テキストをアイコンのすぐ隣に置く方法を探しています。

11
MrEngineer13

[〜#〜]更新[〜#〜]

Googleは非常に類似した機能を備え、新しいウィジェット呼び出しを使用してメニューが通常の方法で膨らむ BottomNavigationView

-元の回答-

みんなこれは私が理解するのに少し時間がかかりました、そしてここであなたはそれが少し重い操作に行きますが、それはうまくいきます。

これをToolbarで使用して、古いSplitActionBar...のように画面の下部に表示します。

ツールバー全体に均等に分散されたMenuItemを保持する

5つか6つを超えるアイテムの使用はお勧めしません。少し混雑する可能性があります...

/**
 * This method will take however many items you have in your  
 * menu/menu_main.xml and distribute them across your devices screen
 * evenly using a Toolbar. Enjoy!!
 */
public void setupEvenlyDistributedToolbar(){
    // Use Display metrics to get Screen Dimensions
    Display display = getWindowManager().getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);

    // Toolbar
    mToolbar = (Toolbar) findViewById(R.id.navigationToolbar);
    // Inflate your menu
    mToolbar.inflateMenu(R.menu.menu_bottom);

    // Add 10 spacing on either side of the toolbar
    mToolbar.setContentInsetsAbsolute(10, 10);

    // Get the ChildCount of your Toolbar, this should only be 1
    int childCount = mToolbar.getChildCount();
    // Get the Screen Width in pixels
    int screenWidth = metrics.widthPixels;

    // Create the Toolbar Params based on the screenWidth
    Toolbar.LayoutParams toolbarParams = new Toolbar.LayoutParams(screenWidth, LayoutParams.WRAP_CONTENT);

    // Loop through the child Items
    for(int i = 0; i < childCount; i++){
        // Get the item at the current index
        View childView = mToolbar.getChildAt(i);
        // If its a ViewGroup
        if(childView instanceof ViewGroup){
            // Set its layout params
            childView.setLayoutParams(toolbarParams);
            // Get the child count of this view group, and compute the item widths based on this count & screen size
            int innerChildCount = ((ViewGroup) childView).getChildCount();
            int itemWidth  = (screenWidth / innerChildCount);               
            // Create layout params for the ActionMenuView
            ActionMenuView.LayoutParams params = new ActionMenuView.LayoutParams(itemWidth, LayoutParams.WRAP_CONTENT);
            // Loop through the children
            for(int j = 0; j < innerChildCount; j++){
                View grandChild = ((ViewGroup) childView).getChildAt(j);
                if(grandChild instanceof ActionMenuItemView){
                    // set the layout parameters on each View
                    grandChild.setLayoutParams(params);
                }
            }
        }
    }
}
10
kandroidj

これをチェックしてください。

<Android.support.v7.widget.Toolbar
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:tools="http://schemas.Android.com/tools"
        xmlns:abc="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/toolbar"
        Android:layout_height="?attr/actionBarSize"
        Android:layout_width="match_parent">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

        <ImageView
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"
            Android:id="@+id/action1"
            Android:background="@color/red_700"/>

        <ImageView
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"
            Android:id="@+id/action2"
            Android:background="@color/red_200"/>

        <ImageView
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"
            Android:id="@+id/action3"
            Android:background="@color/red_100"/>

    </LinearLayout>

</Android.support.v7.widget.Toolbar>

ImageViewを好きなものに置き換えます。

3
natario

このソリューションは、inner_class7、Kuffs、およびMrEngineer13のおかげで、上記の各ソリューションから最良のものを採用しています。
このソリューションは、メニュー項目を均等に分配し、テキストを表示します。

public class EvenlyDistributedToolbarはAndroid.support.v7.widget.Toolbarを拡張します{

    private View actionMenuView;
    public EvenlyDistributedToolbar(Context context) {
        super(context);
        setContentInsetsAbsolute(0, 0);
    }

    public EvenlyDistributedToolbar(Context context, AttributeSet attrs) {
        super(context, attrs);
        setContentInsetsAbsolute(0, 0);
    }

    public EvenlyDistributedToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setContentInsetsAbsolute(0, 0);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        if (child instanceof ActionMenuView) {
            actionMenuView  = child ;
            params.width = LayoutParams.MATCH_PARENT;

            ((ViewGroup)actionMenuView).setOnHierarchyChangeListener(new OnHierarchyChangeListener() {

                @Override 
                public void onChildViewRemoved(View parent, View child) {

                } 

                @Override 
                public void onChildViewAdded(View parent, View child) {
                    if (child instanceof ActionMenuItemView) {
                        //Show the menu item text as well as the the icon
                        ActionMenuItemView actionMenuItemView = (ActionMenuItemView) child;
                        // set the layout parameters on each View
                        actionMenuItemView.setExpandedFormat(true);
                        Drawable[] arr = actionMenuItemView.getCompoundDrawables();

                        if (arr != null && arr.length == 4 && arr[0] != null) {
                            actionMenuItemView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
                        }
                        else if (arr != null && arr.length == 4 && arr[2] != null) {
                            actionMenuItemView.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
                        }
                        actionMenuItemView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
                        actionMenuItemView.setOnLongClickListener(null);

                    }
                } 
            }); 
        }
        super.addView(child, params);
    }


    /**
     * Show All items, call after the menu inflated
     */
    public void showAll() {
        Menu menu = getMenu();

        int size = menu.size();
        for (int i = 0; i < size; i++) {
            MenuItem item = menu.getItem(i);
            // check if app:showAsAction = "ifRoom"
            if (((MenuItemImpl) item).requestsActionButton()) {
                item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS);
            }
        }
    }


}

        <com.util.EvenlyDistributedToolbar
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content" />
1
avi

下のツールバーに等間隔のボタンが欲しかったので、ここに私が別の同様の質問に対して投稿したソリューションがあります: Androidは同じアクティビティに2つのツールバーを追加します

1

私の推奨は 設計ガイドライン に従うことです。 toolbar を使用している場合は、 men の項目をそのままにしておいてください。

enter image description here

ただし、等間隔が必要な場合は、 タブ の使用を検討してください。

enter image description here

または ボトムナビゲーションバー

enter image description here

この回答 は、ボトムナビゲーションバーの設定方法を示します。

0
Suragch

kandroidjによってpublic void setupEvenlyDistributedToolbar(){}によって提案されたソリューションは完全に機能します。ただし、ソリューションをもう少し完成させるには、カスタムOnclickListenerが必要です。

添付は私の実装です

private void setupOnClickListener4Toolbar(Toolbar toolbar) {
    Menu bottomMenu = toolbar.getMenu();
    for (int i = 0; i < bottomMenu.size(); i++) {
        bottomMenu.getItem(i).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                return onOptionsItemSelected(item);
            }
        });
    }
}
0
Pedro Campos

リソースからインフレートするのではなく、プログラムでメニューを作成する場合、これを行うことができます。

別の回答で述べたようにSplitToolbarを使用します。通常どおりFindViewByIdを使用してツールバーへの参照を取得します。ツールバーがレイアウトに存在しない場合、メニューは通常の非分割バージョンとして機能します。

import Android.content.Context;
import Android.support.v7.widget.ActionMenuView;
import Android.support.v7.widget.Toolbar;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;

public class SplitToolbar extends Toolbar {
    public SplitToolbar(Context context) {
        super(context);
    }

    public SplitToolbar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SplitToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        if (child instanceof ActionMenuView) {
            params.width = LayoutParams.MATCH_PARENT;
        }
        super.addView(child, params);
    }
}

次に、メニュー作成コードで次のようにします。

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    if (toolbar != null) {
       toolbar.setContentInsetsAbsolute(0,0);
        menu = toolbar.getMenu();
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                // Call back to the original menu code to handle menu clicks
                return onOptionsItemSelected(menuItem);
            }
        });
    }

    // Now build your menu as normal
    menu.clear();

    MenuItem b = menu.add(0, WHATEVER, 0, R.string.WHATEVER);
             b.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
             b.setIcon(R.drawable.ic_menu_encrypt);
    // End of normal menu code

    // Now set the button options.
    if (toolbar != null) {
        int size = menu.size();
        for (int i = 0; i < size; i++) {
            MenuItem item = menu.getItem(i);
            // check if app:showAsAction = "ifRoom"
            if (((MenuItemImpl) item).requestsActionButton()) {
                item.setShowAsAction(SupportMenuItem.SHOW_AS_ACTION_ALWAYS);
            }
        }
    }
    Return true; 
}
0
Kuffs