为什么 Layoutflater 会忽略我指定的晒版宽度和晒版高度的布局参数?

我遇到了严重的问题,使 Layoutflater 按照预期工作,其他人也遇到了同样的问题: 如何使用布局膨胀器在运行时添加视图?

为什么 Layoutflater 忽略了我指定的布局参数?例如,为什么我的资源中的 layout_widthlayout_height值没有得到尊重?

103097 次浏览

我已经调查了这个问题,参考了 布局并建立了一个小样本示范项目。下面的教程演示如何使用 LayoutInflater动态填充布局。

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

  • Resource : 要加载的 XML 布局资源的 ID (例如,R.layout.main_page)
  • Root : 可选视图是生成的层次结构的父级(如果 attachToRoottrue) ,或者仅仅是一个对象,为返回的层次结构的根提供一组 LayoutParams值(如果 attachToRootfalse)
  • AttachToRoot : 膨胀的层次结构是否应该附加到 root 参数?如果为 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_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

添加到这个容器中的是一个单独的 TextView,如果从 XML (red.xml)成功应用了布局参数,则可以看到小红方框:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="25dp"
android:layout_height="25dp"
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);
}
}

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

SYNOPSIS: 调用 LayoutInflater而不指定 root 导致忽略来自 XML 的布局参数的调用膨胀。使用 root 不相等的 nullattachRoot=true调用充气确实会加载布局参数,但是会再次返回 root 对象,这样就可以防止对加载的对象进行进一步的布局更改(除非您可以使用 findViewById()找到它)。 因此,您最可能使用的调用约定是:

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

为了帮助解决布局问题,强烈推荐使用 布局督察

使用 anddig 是正确的,Layoutflater 忽略您的 lay_ params 的一个常见原因是因为没有指定根用户。许多人认为您可以将 null 作为 root 传入。这对于一些场景(如对话框)是可以接受的,在这些场景中,您在创建时无法访问 root。但是,一个很好的规则是,如果您有 root,那么将它交给 Layoutflater。

我写了一篇关于这方面的深度博文,你可以点击这里查看:

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

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

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

我已经通过 xml 添加了这些参数,但它不能正确工作
有了这条线,一切都好了