当 AlertDialog 使用膨胀视图时,“避免将 null 作为视图根传递”警告

我得到的线头警告,Avoid passing null as the view root时,充气视图 null作为 parent,像:

LayoutInflater.from(context).inflate(R.layout.dialog_edit, null);

然而,这个视图将被用作 AlertDialog的内容,在 AlertDialog.Builder上使用 setView,所以我不知道应该传递什么作为 parent

你认为 parent在这种情况下应该是什么?

49214 次浏览

使用此代码可在没有警告的情况下膨胀对话框视图:

View.inflate(context, R.layout.dialog_edit, null);

简而言之,当您为一个对话框充气一个视图时,parent应该为空,因为在视图充气时它是未知的。在这种情况下,您有三个基本的解决方案来避免这种警告:

  1. 使用@Suppress 取消警告
  2. 使用 View 的 充气法充气法充气法来充气视图。这只是一个包装版本膨胀器的包装,主要是混淆问题。
  3. 使用 Layoutflater 的 完整方法: inflate(int resource, ViewGroup root, boolean attachToRoot)对视图进行充气。将 attachToRoot设置为 false。这告诉充气机父级不可用。在旧版本的 Android Lint 中,这样做删除了警告。在后1.0版本的 Android Studio 中,情况不再是这样。

请查看 http://www.doubleencore.com/2013/05/layout-inflation-as-intended/以获得关于这个问题的讨论,特别是最后的“每个规则都有一个异常”部分。

ViewGroup 解决了以下警告:

View dialogView = li.inflate(R.layout.input_layout,(ViewGroup)null);

其中 liLayoutInflater's对象。

而不是去做

view = inflater.inflate(R.layout.list_item, null);

view = inflater.inflate(R.layout.list_item, parent, false);

它将使用给定的父级对其进行膨胀,但不会将其附加到父级。

非常感谢 Coeffect (链接到他的帖子)

当您实际上没有任何 parent(例如为 AlertDialog创建视图)时,除了传递 null之外别无选择。因此,这样做是为了避免警告:

// Java
final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);


// Kotlin
val nullParent: ViewGroup? = null
val convertView = layoutInflater.inflate(R.layout.my_dialog, nullParent)

您应该使用 AlertDialog.Builder.setView(your_layout_id),这样就不需要对它进行充气。

创建对话框后使用 AlertDialog.findViewById(your_view_id)

使用 (AlertDialog) dialogInterface获取 OnClickListener内部的 dialog,然后获取 dialog.findViewById(your_view_id)

您不需要为对话框指定 parent

在覆盖的顶部使用 @SuppressLint("InflateParams")来抑制它。

  1. 就我所知,AlertDialog 是唯一可以安全地使用 无效而不是父视图的情况。在这种情况下,您可以使用以下方法禁止显示警告:

    @ SuppressLint (“膨胀参数”)

  2. 通常,您不应该使用 SupressLint 或其他答案中提到的变通方法之一来消除警告。父视图对于评估布局参数是必要的,这些参数是在充气视图的根元素中声明的。这意味着如果使用 无效而不是父视图,根元素中的所有 Layout Params 将被忽略,并被默认的 Layout Params 替换。大多数情况下,它会很好,但在某些情况下,它会导致一个真正难以找到的错误。

View.inflate()的文档中可以看出

从 XML 资源膨胀视图 LayoutInflater类,它为视图膨胀提供了全面的选项。

  @param context The Context object for your activity or application.
@param resource The resource ID to inflate
@param root A view group that will be the parent.  Used to properly inflate the  layout_* parameters.

根据 https://developer.android.com/guide/topics/ui/dialogs

充气并设置对话框的布局
将 null 作为父视图传递,因为它将进入对话框布局

因此,对于创建 AlertDialog,我使用 @SuppressLint("InflateParams")

LayoutInflater inflater = requireActivity().getLayoutInflater();
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view);

Android 的文档(AlertDialog)显示:

如果你想显示一个更复杂的视图,查找 FrameLayout,称为“自定义”并添加你的视图:

FrameLayout fl = findViewById(android.R.id.custom);
fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));

因此,在我们的示例中,我们可以使用 fl作为父代:

FrameLayout fl = findViewById(android.R.id.custom);
View view = LayoutInflater.from(context).inflate(R.layout.custom_dialog, fl, false);

它能用,但我不确定它是否有效