【问题标题】:"Avoid passing null as the view root" warning when inflating view for use by AlertDialog膨胀视图以供 AlertDialog 使用时出现“避免将 null 作为视图根传递”警告
【发布时间】:2014-12-11 20:27:38
【问题描述】:

当使用 null 将视图膨胀为 parent 时,我收到了 lint 警告 Avoid passing null as the view root,例如:

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

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

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

【问题讨论】:

  • 传递 false 而不是 null。见this
  • 尝试给你父布局而不是 null 然后不要使用 setView。
  • 我禁止该方法的 lint 警告。我还没有找到不应该通过null 的充分理由。
  • 我理解布局问题取决于父视图,但这并不真正适用于本质上浮动在 Activity 视图层次结构之上的 AlertDialog。这就是为什么你可以通过null。您可以抑制 lint 是有原因的。 Lint 应该为您经常遗漏的问题提供警告;在这种情况下,它是正确的调用。
  • @ashutiwari4 我每天都在学习新事物......美丽的世界:我

标签: android android-alertdialog layout-inflater


【解决方案1】:

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

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

【讨论】:

  • @MarianPaździoch 因为它不会引起警告。 :-) 当然,这引出了为什么 lint 代码对 View.inflateLayoutInflator.inflate 的处理方式不同的问题。我还没有看到明确的答案。这可能与为什么有两种看似等效的方法可以夸大同一个视图有关,而我也没有看到理由。
  • 这是错误的。它只会抑制警告,但问题仍然存在。阅读possiblemobile.com/2013/05/layout-inflation-as-intended 以获得更好的解决方案。
  • @JonaChristopherSahnwaldt 你能详细说明一下吗?文章说 AlertDialog 应该有一个 null 父级,因为它没有根视图。对我来说,这似乎强化了警告对对话框外的视图有意义,但不适用于对话框视图。
  • @EdwardBrey 你是对的——我没有仔细阅读这篇文章。在这种特殊情况下,可以使用View.inflate(...null)@SuppressLint。一般来说,LayoutInflater.from(...).inflate(..., parent, false) 更好。感谢您指出这一点!
  • @Bevor Avoid passing null 的问题是关于您有父母的情况。这个问题是关于AlertDialog,它没有为被膨胀的视图提供父级。在扩展 AlertDialog 的根视图时,传递 null 是正确的。 Lint 没有考虑到这个特定的上下文,因此如果您使用将parent 误报的函数,它会给出警告,而不是表示任何容易出错的迹象。这就是为什么在这种情况下使用不接受 parent 并且不触发警告的函数是有效的。
【解决方案2】:

简短的故事是,当您为对话框膨胀视图时,parent 应该为空,因为在视图膨胀时它是未知的。在这种情况下,您可以通过三种基本解决方案来避免该警告:

  1. 使用@Suppress 抑制警告
  2. 使用 View 的 inflate method 为 View 充气。这只是一个 LayoutInflater 的封装,主要是为了混淆问题。
  3. 使用 LayoutInflater 的 full method: inflate(int resource, ViewGroup root, boolean attachToRoot) 为视图充气。将 attachToRoot 设置为 false。这会告诉充气机父级不可用。 在旧版本的 Android Lint 中,这会删除警告。 Android Studio 1.0 后版本不再是这种情况。

查看http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ 以获得对此问题的精彩讨论,特别是最后的“每个规则都有例外”部分。

【讨论】:

    【解决方案3】:

    你应该使用AlertDialog.Builder.setView(your_layout_id),所以你不需要膨胀它。

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

    使用(AlertDialog) dialogInterfaceOnClickListener 中获取dialog,然后使用dialog.findViewById(your_view_id)

    【讨论】:

    • 这是要走的路!只需创建对话框,然后找到您的视图。
    • 这是一个很好的方法,但是请记住这个method 是在 API 21 中添加的
    • 如果我们必须将这个膨胀的布局存储在某个变量中怎么办?例如,我写了一个类A,其中有方法onCreateDialog。在后者中,我按照你所说的alert_dialog_builder.setView(R.layout.edit_account_dialog); 写了。但我必须将这个膨胀的布局存储在名为the_inflated_layout_of_the_dialogA 的属性变量中。
    【解决方案4】:

    将 null 转换为 ViewGroup 解决了警告:

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

    其中liLayoutInflater's 对象。

    【讨论】:

    • 其中 'li' 是 LayoutInflater 对象。
    • 这个答案是最好的,只要你明白你为什么要这样做。正如您可能已经读过的那样,短篇小说是 AlertDialog 在膨胀时不知道其父级,因此当您实际上在做正确的事情时,lint 在这种精确情况下会引发警告,这是一个副作用。
    • 但它是多余的铸造
    • 然后我们收到另一个警告“铸造是多余的”!
    • 你在开玩笑吗?
    【解决方案5】:

    您无需为对话框指定parent

    使用覆盖顶部的@SuppressLint("InflateParams") 来抑制这种情况。

    【讨论】:

      【解决方案6】:

      当您真的没有任何parent(例如为AlertDialog 创建视图)时,您别无选择,只能传递null。所以这样做是为了避免警告:

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

      【讨论】:

      • 它会产生另一个警告“值 'nullParent' 始终为空。”
      • 从 AndroidStudio 3.3 和 API 28 开始,这是唯一可行的解​​决方案。
      【解决方案7】:

      根据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);
      

      【讨论】:

        【解决方案8】:
        1. 据我所知,AlertDialog 是您可以安全地使用 null 而不是父视图的唯一情况。在这种情况下,您可以使用以下命令抑制警告:

          @SuppressLint("InflateParams")

        2. 一般来说,您永远不应该使用 SupressLint 或其他答案中提到的解决方法之一来消除警告。父视图是评估在被膨胀视图的根元素中声明的布局参数所必需的。这意味着如果您使用 null 而不是父视图,则根元素中的所有布局参数都将被忽略并被默认布局参数替换。大多数时候它会很好,但在某些情况下会导致一个非常难以发现的错误。

        【讨论】:

          【解决方案9】:

          Android 的文档 (AlertDialog) 说:

          如果您想显示更复杂的视图,请查找名为“custom”的 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);
          

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

          【讨论】:

            【解决方案10】:

            而不是做

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

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

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

            非常感谢 Coeffect (link to his post)

            【讨论】:

            • 知道如何获得父母也很有用。
            【解决方案11】:

            来自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.
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-09-10
              • 2011-11-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多