Что я должен передать для 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
- Передайте результат на надув.
Это похоже на работу. Может ли кто-нибудь подтвердить или опровергнуть, нужно ли это делать?
Ответы
Ответ 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();