2014-10-21 4 views
17

Так что я пытался реализовать android.support.v7.widget.Toolbar в своей деятельности и сделать его похожим на ранее поддерживаемый split 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

+0

Я знаю, что с помощью ActionBar существует вызов 'setCustomView(), который может быть использован для потенциального получения шаблона проектирования, который будет нужен. И кажется, что сам класс «ToolBar» также быстро поддерживает несколько пользовательских представлений. Затем вы сможете использовать 'LinearLayout' с весами. –

+0

Не могли бы вы помочь в этом http://stackoverflow.com/questions/27270722/issues-in-using-new-toolbar-component-hiding-and-showing-navigation-drawer-icon/27273568?noredirect=1#comment43047261_27273568 – Dory

+0

MrEngineer13 - Вам повезло с решением этой проблемы? Просто столкнулся с этим сегодня вечером и попытался найти способ заставить его работать, как splitActionBar. Теоретически, макет панели инструментов может содержать представление кнопки для каждого значка, но это явно побеждает цель «меню». Я использовал этот подход в своем приложении для пользовательского значка меню (ползунок выдвижного ящика), но я не хочу слишком много накладных расходов для общих пунктов меню ... – Kyle

ответ

10

Here's что работало * для меня:

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

Layou t.xml

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

Когда я говорю, работал я имею в виду, что в центре все, что в моем меню, текст, так и изображения. Если вы используете только значки для своего меню, тогда он будет выглядеть великолепно. Я все еще ищу способ сосредоточить их, и текст будет рядом с значками.

+1

Это отлично работает, с одним незначительным оговоркой (кроме вышеупомянутого) - горизонтальное выравнивание выключено. Самый левый значок имеет больший запас, чем самый правый. У меня есть 4 в моей «сплит-панели», и они, похоже, не выстраиваются в линию, как вы ожидали. Это более заметно с 5 - значок центра сдвигается вправо на 10 дп ~. Не большая проблема, но достаточно для OCD, чтобы в нее влезть ;-) В противном случае, спасибо за усилия по этому - это намного лучше, чем дефолт от Google. По общему правилу только 1 FAB, я не знаю, как они ожидают, что работа будет работать без разделительной панели действий ... – Kyle

+2

Смещение может быть встречено вызовом toolbar.setContentInsetsAbsolute (0,0); – Kuffs

+0

@ Kuffs - очень приятно. Спасибо. Я удалил contentInsert из определения XML, но не думал проверять, чтобы делать в коде. Спасибо - это отлично работает, OCD может легко отдохнуть! – Kyle

2

Проверь это.

<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 с тем, что вы хотите.

0

При создании меню программно, а не надувать из ресурсов, вы можете сделать это:

Используйте 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; 
} 
8

Ребята, это заняло у меня некоторое время, чтобы понять, и вот вы немного поработали, но это работает.

Я использую это на Toolbar для отображения в нижней части экрана, как старый SplitActionBar ...

Созерцайте равномерно распределенную MenuItems через панель инструментов

Я бы не рекомендовал использовать более 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); 
       } 
      } 
     } 
    } 
} 
+1

Спасибо. Я нашел это наиболее удобным способом; Я мог бы объявить и использовать панель инструментов как обычно, просто должен был позвонить этому методу. Нет необходимости в пользовательских панелях инструментов, надувных устройствах и т. Д. – Mendhak

+0

@ Mendhak не проблема! –

+0

Это отлично работает, за исключением экранов с низким разрешением. У меня есть панель инструментов внизу с 5 видимыми элементами, а остальное - в меню переполнения. На экранах шириной более 320 дп все выглядит нормально (C). При низких разрешениях (ширина: 320 пикселей ldpi) последняя кнопка перекрывает меню переполнения (B). Если вы удалите строку childView.setLayoutParams (toolbarParams); нет перекрытия, но кнопки не центрированы по вертикали (A). [скриншоты] (http://i.imgur.com/N3fV2OI.png) – floppes

0

Вот решение, которое я отправил на другой аналогичный вопрос, так как на моей нижней панели инструментов I хотел равноудаленных кнопки: android add two toolbars in the same activity

1

Это решение взять лучшее от каждого из вышеуказанных решений, Благодаря inner_class7, Каффс & MrEngineer13.
Это решение равномерно распределяет пункты меню и отображает текст.

общественного класса 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

Моя рекомендация состоит в том, чтобы следовать design guidelines. Если вы используете toolbar, оставьте пункты menu, где они предназначены для перехода.

enter image description here

Однако, если вы хотите равные промежутки, то рекомендуется использовать Tabs

enter image description here

или Bottom Navigation Bar

enter image description here

This answer рассказывает, как создать Bottom Панель навигации.