Расширение пользовательского представления вручную дает разные макеты для пользовательского представления ActionBar.

Пользовательский вид из ресурса:

// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setCustomView(R.layout.custom_action_bar);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

результат:
введите здесь описание изображения

Пользовательский вид, завышенный вручную:

// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
LayoutInflater inflater = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_action_bar, null);
actionBar.setCustomView(view);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

результат:
введите здесь описание изображения

custom_action_bar.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" 
    android:weightSum="3">

    <TextView 
        android:id="@+id/bar_title1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title1"/>
    <TextView 
        android:id="@+id/bar_title2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title2"/>
    <TextView 
        android:id="@+id/bar_title3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title3"/>

</LinearLayout>

Первый макет, показанный здесь, является правильным, потому что его виджеты имеют веса. Вторая попытка должна дать тот же результат, но это не так.


person ilomambo    schedule 08.07.2013    source источник
comment
можете ли вы изменить в custom_action_bar.xml я изменил android:layout_width = fill_parent и удалил android:weightSum=3 ‹LinearLayout xmlns:android=schemas.android.com/apk/res/android android:layout_width=fill_parent android:layout_height=match_parent android:orientation=horizontal › Можете ли вы поделиться результатом, если он работает для вас?   -  person Roll no1    schedule 08.07.2013
comment
@ Rollno1 Я пробовал. Ваше решение работает, часть fill_parent не нужна (fill_parent эквивалентно match_parent). Удаление атрибута weightsum помогает.   -  person ilomambo    schedule 08.07.2013


Ответы (2)


На самом деле проблема здесь в том, что во втором случае ActionBar нужны дополнительные параметры макета:

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.custom_action_bar, null);
    actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

Таким образом, он охватывает всю область ActionBar. Похоже, что по умолчанию WRAP_CONTENT параметры макета применяются к пользовательскому виду.

person sandrstar    schedule 08.07.2013
comment
Интересно. Я попробовал ваш код, и вы правы. Несмотря на то, что в пользовательском макете match_parent уже определены ширина и высота. - person ilomambo; 08.07.2013
comment
Верно, но для применения родительская ViewGroup должна быть передана в inflate(). На самом деле ActionBarImpl использует внутреннюю ViewGroup во время инфляции в методе setCustomView(int resId) - например. setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); - person sandrstar; 08.07.2013
comment
Я сходил с ума, чтобы сопоставить все пространство с моей панелью действий custon. Наконец, я сделал это, добавив LayoutParams, как сказал sandrstar. - person rolgalan; 18.11.2014

Другой вариант — позволить панели действий сделать всю работу за вас (в данном случае я показываю, как это сделать в версии поддержки).

// Set your custom view
getSupportActionBar().setCustomView(R.layout.custom_action_bar);

// Get the inflated view
View view = getSupportActionBar().getCustomView();

// Do what you want with the view (set the title, custom font etc.)
TextView actionBarTitle = (TextView) view.findViewById(R.id.action_bar_title);
...

// set the custom flag
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM)
person petrocket    schedule 03.02.2014
comment
Умный ход, мистер! ИМХО, это должен быть принятый ответ. Использование Layout Inflater с «нулем» в качестве корневого представления является «корнем всех зол» для многих проблем с макетом, поскольку параметры layout_*, связанные с родителем, игнорируются при инфляции. - person Maciej Pigulski; 08.07.2014
comment
Отличный ответ! Решил мою проблему с макетом сразу. - person Matthias Robbers; 18.10.2014
comment
@MaciejPigulski «null» в корне не является первопричиной, первопричина заключается в непонимании того, зачем вообще нужен «root». Единственный способ исправить это - RTFM. - person sandrstar; 31.01.2015
comment
@sandrstar, спасибо за вашу ценную информацию, особенно за часть RTFM, очень полезно! - person Maciej Pigulski; 02.02.2015