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

我已经遇到了严重的麻烦让LayoutInflater按预期工作,其他人也如此: 如何使用layoutinflator在运行时添加视图? 。

为什么LayoutInflater忽略我指定的布局参数? 例如,为什么我的资源XML中的layout_widthlayout_height值不符合要求?

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

在开始之前,请参阅LayoutInflater.inflate()参数的外观:

  • 资源 :要加载的XML布局资源的标识(例如R.layout.main_page
  • root :可选视图是生成的层次结构的父级(如果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_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); } } 

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

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

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

为了帮助解决布局问题,强烈建议使用层次结构查看器 。

andig是正确的,LayoutInflater忽略你的layout_params的一个常见原因是因为一个根没有被指定。 许多人认为你可以通过null为根。 这对于一些场景是可以接受的,例如在创建时无法访问根的对话框。 然而,一个好的规则是,如果你有root权限,把它给LayoutInflater。

我写了一篇关于这个的深入的博客文章,你可以在这里看看:

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