当我膨胀一个布局用于MenuItem的ActionView时,应该传递什么参数作为根节点?

43

我有一个ImageView,将其附加到一个MenuItem作为其ActionView(该项目出现在ActionBar中)。此视图的布局来自XML。我是这样膨胀它的:

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

这似乎运行得很好。然而,在调用inflate()时将null传递给root会导致 Lint 报错:

避免将 null 作为视图根传递(需要解析已膨胀布局的根元素上的布局参数)

在我的特定情况下,我似乎可以没有根,但我宁愿代码尽可能正确。问题是,我不确定哪个View应该在这里用作根。 这个答案说应该是“包围您要填充的视图对象的小部件”。但是这在这里意味着什么?操作栏的那一个?活动?还是完全不同的东西?


更新:阅读答案使我怀疑我应该做正确的事情:

  1. 获取与MenuItem对应的ActionBar View
  2. 获取其根
  3. 将根强制转换为ViewGroup
  4. 将结果传递给inflater

这似乎有效。有人可以确认或否认是否应该这样做吗?


7
关于这个问题,有一篇很好的文章:http://www.doubleencore.com/2013/05/layout-inflation-as-intended/(即关于膨胀的问题,而不是关于问题本身)。 - Avinash R
3个回答

26

我会这样简单地做:

menuItem.setActionView(R.layout.action_view_layout);

让安卓为您填充视图。
如果您需要对此 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;
}

哇,我甚至不知道重载这个功能存在。使用它意味着我不能缓存通货膨胀的结果并在以后重用它(因为我多次分离和重新连接ActionView),但也许我本来就不应该这样做。感谢您展示了该函数实际所做的操作;猜想我把它想复杂了。 - dlf
我不认为你需要将它缓存起来,但如果你有疑问,请提出另一个问题,并在此处粘贴链接,这样我就可以跟踪并给你答案。别忘了发布你的代码。点赞! - Damian Petla
我绝对不是“需要”这样做;我只是想节省每次膨胀布局的成本。但这肯定是一种过早的优化。 - dlf

15
请看这里,它很好地解释了布局膨胀器。
在标准应用程序中,有两个可用版本的inflate()方法:
inflate(int resource, ViewGroup root)
inflate(int resource, ViewGroup root, boolean attachToRoot)

第一个参数指向您要膨胀的布局资源。第二个参数是您要将资源膨胀到的层次结构的根视图,以便附加到其上。当第三个参数存在时,它控制在膨胀后是否将膨胀的视图附加到提供的根视图上。
正是这两个参数可能会引起一些混淆。使用此方法的两个参数版本时,LayoutInflater会自动尝试将膨胀的视图附加到提供的根视图上。但是,框架已经放置了一个检查,如果您将根参数传递为null,则绕过此尝试以避免应用程序崩溃。
许多开发人员认为这种行为意味着禁用膨胀时的正确方法是通过将根设置为null。在许多情况下,他们甚至没有意识到inflate()的三个参数版本存在。 更多关于布局膨胀的内容

4
这个回答只是从文章中复制并解释了什么是(良好的)通货膨胀。提问者可能已经知道这一点,并且正在询问一个特殊情况,而这个回答并没有增加任何内容。 - avalancha

5

通常情况下,您需要将要添加actionView的(ViewGroup子类)传递给inflate函数。为了从inflate调用中获取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's parent
menuItem.addActionView(actionView)

这里有一个非常好的教程(链接),它以不同的方式处理事情。它在menu.xml中指定了action_view_layout,类似于:

android:actionLayout="@layout/action_view_layout"

如果您使用相同的布局,这可能也适用于您。如果您选择这种方式,您可以通过以下方法获取ActionView

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接