为啥 LayoutInflater 会忽略我指定的 layout_width 和 layout_height 布局参数?

Posted

技术标签:

【中文标题】为啥 LayoutInflater 会忽略我指定的 layout_width 和 layout_height 布局参数?【英文标题】:Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified?为什么 LayoutInflater 会忽略我指定的 layout_width 和 layout_height 布局参数? 【发布时间】:2011-06-28 22:55:30 【问题描述】:

让 LayoutInflater 按预期工作时遇到了严重问题,其他人也是如此:How to use layoutinflator to add views at runtime?。

为什么 LayoutInflater 会忽略我指定的布局参数?例如。为什么我的资源 XML 中的 layout_widthlayout_height 值不被接受?

【问题讨论】:

是的——这会伤害还是我选错了地方?只是想我会分享我的结果。必须承认教程没有特别提到常见问题页面.. 见常见问题解答中第一个问题的最后一段。将其作为问题发布,然后将教程作为答案发布。当然,您可以编辑此问题并在答案中剪切和粘贴教程。如果你解决这个问题,我会投票赞成。 【参考方案1】:

我已经调查过这个问题,参考LayoutInflater docs 并设置了一个小样本演示项目。以下教程展示了如何使用 LayoutInflater 动态填充布局。

在我们开始之前,看看LayoutInflater.inflate() 参数是什么样的:

resource:要加载的 XML 布局资源的 ID(例如,R.layout.main_pageroot:作为生成层次结构的父级的可选视图(如果attachToRoottrue),或者只是为返回层次结构的根提供一组LayoutParams 值的对象(如果attachToRootfalse。)

attachToRoot:膨胀的层次结构是否应该附加到根参数?如果为 false,则 root 仅用于为 XML 中的根视图创建 LayoutParams 的正确子类。

返回:膨胀层次结构的根视图。如果提供了 root 并且 attachToRoottrue,则这是 root;否则它是膨胀的 XML 文件的根。

现在是示例布局和代码。

主布局(main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_
    android:layout_>
</LinearLayout>

添加到此容器中的是一个单独的 TextView,如果布局参数从 XML 成功应用,则显示为红色小方块 (red.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="#ff0000"
    android:text="red" />

现在LayoutInflater 与多种调用参数一起使用

public class InflaterTest extends Activity 

    private View view;

    @Override
    public void onCreate(Bundle savedInstanceState) 
      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);
      ViewGroup parent = (ViewGroup) findViewById(R.id.container);

      // result: layout_height=wrap_content layout_width=match_parent
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view);

      // result: layout_height=100 layout_width=100
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view, 100, 100);

      // result: layout_height=25dp layout_width=25dp
      // view=textView due to attachRoot=false
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
      parent.addView(view);

      // result: layout_height=25dp layout_width=25dp 
      // parent.addView not necessary as this is already done by attachRoot=true
      // view=root due to parent supplied as hierarchy root and attachRoot=true
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
    

参数变化的实际结果记录在代码中。

概要: 在不指定 root 的情况下调用 LayoutInflater 会导致膨胀调用忽略 XML 中的布局参数。使用 root 不等于 nullattachRoot=true 调用 inflate 确实会加载布局参数,但会再次返回根对象,这会阻止对加载的对象进行进一步的布局更改(除非您可以使用 findViewById() 找到它)。 因此,您最有可能使用的调用约定是这个:

loadedView = LayoutInflater.from(context)
                .inflate(R.layout.layout_to_load, parent, false);

为了帮助解决布局问题,强烈建议使用Layout Inspector。

【讨论】:

优秀的答案。已经在 Android 上工作了 3 年,而且还在不断增加,但仍然可以从中学到一些东西。 嗨,有没有办法用 java 代码做同样的事情,而不是用 R.layout 膨胀。因为我没有布局。我用 java 代码创建了视图,我想添加相同的视图 300 次。 @andig: ActivityContext 的子类,答案的示例在Activity 的范围内,所以为了简单起见,我将getBaseContext() 替换为this,因为为了这个答案,它是等价的。 容器的 layout_width 和 layout_height 设置为“match_parent”;然后评论说“//结果:layout_height=wrap_content layout_width=match_parent”。我错过了什么吗? 感谢您进行研究并分享结果!另外,我同意玛丽安的问题。【参考方案2】:

andig 是正确的,LayoutInflater 忽略您的 layout_params 的一个常见原因是因为未指定根。许多人认为您可以将 null 传递给 root。这对于一些场景(例如对话)是可以接受的,在这些场景中,您在创建时无权访问 root。但是,要遵循的一个好规则是,如果您有 root,请将其提供给 LayoutInflater。

我为此写了一篇深入的博文,您可以在这里查看:

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/

【讨论】:

This is acceptable for a few scenarios such as a dialog 这就是我所需要的【参考方案3】:

想添加到上面的主要答案 我试图跟随它,但我的 recyclerView 开始将每个项目拉伸到屏幕上 为了达到目标,我必须在充气后添加下一行

itemLayoutView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));

我已经通过 xml 添加了这些参数,但它没有正常工作 这条线一切正常

【讨论】:

以上是关于为啥 LayoutInflater 会忽略我指定的 layout_width 和 layout_height 布局参数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Git 不忽略我指定的文件?

为啥使用 LayoutInflater 与 xml 不同?

[Android] 转-LayoutInflater丢失View的LayoutParams

为啥我在 SwiftUI 中的 TextEditor 会忽略我的 .keyboardType?

为啥 flyway 会忽略我的 SQL 迁移文件?

为啥我以编程方式创建的视图会忽略其约束?