Подтвердить что ты не робот

Что я должен передать для root при раздувании макета для использования в MenuItem ActionView?

У меня есть ImageView, который я прикрепляю к MenuItem как к ActionView (элемент появляется в ActionBar). Макет для этого представления поступает из XML. Я раздуваю его так:

ImageView actionView = (ImageView) layoutInflater.inflate(
   R.layout.action_view_layout, null);

Это работает нормально. Однако; прохождение null для root в вызове inflate() делает Lint yell у меня:

Избегайте передачи null в качестве корня представления (необходимо разрешить компоновку параметры на корневом элементе раздутого макета)

Я могу, по-видимому, обойтись без корня в моем конкретном случае, но я предпочел бы, чтобы код был как можно более правильным. Проблема в том, что я не уверен, какой View следует использовать в качестве корня здесь. Этот ответ говорит, что это должен быть "виджет, окружающий объекты вида, которые вы хотите раздуть". Но что это значит? Один для панели действий? Активность? Что-то еще полностью?


Обновление: Чтение ответов заставило меня подозревать, что я должен сделать следующее:

  • Получить ActionBar View, соответствующий MenuItem
  • Получить свой корень
  • Вставьте корень в ViewGroup
  • Передайте результат на надув.

Это похоже на работу. Может ли кто-нибудь подтвердить или опровергнуть, нужно ли это делать?

4b9b3361

Ответ 1

Я бы просто сделал это вот так:

menuItem.setActionView(R.layout.action_view_layout);

Позвольте Android раздуть представление для вас.

Если вам нужно внести дополнительные изменения в этот вызов ImageView

ImageView imageView = (ImageView) menuItem.getActionView();

Обновление

Чтобы удовлетворить ваше любопытство. Вот что делают люди из Google под капотом:

public MenuItem setActionView(int resId) {
    final Context context = mMenu.getContext();
    final LayoutInflater inflater = LayoutInflater.from(context);
    setActionView(inflater.inflate(resId, new LinearLayout(context), false));
    return this;
}

Ответ 2

Вы смотрите на это. он также прекрасно объясняет Макетный инфлятор.

Для стандартного приложения существуют две доступные версии метода inflate():

inflate(int resource, ViewGroup root)
inflate(int resource, ViewGroup root, boolean attachToRoot)

Первый параметр указывает на ресурс макета, который вы хотите раздуть. Второй параметр - это корневой вид иерархии, на которой вы накапливаете ресурс для присоединения. Когда третий параметр присутствует, он определяет, прикреплен ли задутый вид к поданному корню после инфляции.

Именно эти последние два параметра могут вызвать путаницу. В двухпараметрической версии этого метода LayoutInflater автоматически попытается подключить надутое представление к предоставленному корню. Тем не менее, в структуре есть проверка, что, если вы передаете null для корня, он обходит эту попытку, чтобы избежать сбоя приложения.

Многие разработчики берут это поведение, чтобы означать, что правильный способ отключить привязанность к инфляции - это передать null как root; во многих случаях даже не понимая, что существует трехпараметрическая версия inflate().

Подробнее о макетах инфляции

Ответ 3

Как правило, вы хотите передать любой (подкласс класса ViewGroup), который вы собираетесь добавить для активации actionView. для того, чтобы получить actionView обратно из вызова надувания, а не родителя, вы хотите добавить третий параметр, false, чтобы он не добавлял раздутый вид к родительскому.

ImageView actionView = 
    (ImageView)layoutInflater.inflate(R.layout.action_view_layout, parent, false);
// .. do whatever you like with actionView and then add it to it parent
menuItem.addActionView(actionView)

Там довольно хороший учебник здесь, который идет о вещах немного по-другому. Он указывает action_view_layout как часть menu.xml с чем-то вроде:

android:actionLayout="@layout/action_view_layout"

Это также может работать для вас, если вы всегда используете один и тот же макет. если вы пройдете по этому маршруту, вы сможете получить ActionView, выполнив

ImageView actionView = menu.findItem(R.id.whatever).getActionView();