为什么LayoutInflater会忽略我指定的layout_width和layout_height布局参数?
我已经遇到了严重的麻烦让LayoutInflater按预期工作,其他人也如此: 如何使用layoutinflator在运行时添加视图? 。
为什么LayoutInflater忽略我指定的布局参数? 例如,为什么我的资源XML中的layout_width
和layout_height
值不符合要求?
我已经调查过这个问题,参考了LayoutInflater文档并设置了一个小示例演示项目。 以下教程显示如何使用LayoutInflater
动态填充布局。
在开始之前,请参阅LayoutInflater.inflate()
参数的外观:
- 资源 :要加载的XML布局资源的标识(例如
R.layout.main_page
) - root :可选视图是生成的层次结构的父级(如果
attachToRoot
为true
),或者只是为返回的层次结构的根提供一组LayoutParams
值的对象(如果attachToRoot
为false
。 -
attachToRoot :膨胀层次结构是否应该附加到根参数? 如果为false,则root仅用于为XML中的根视图创建
LayoutParams
的正确子类。 -
返回 :充气层次的根视图。 如果提供了root并且
attachToRoot
为true
,则这是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
不等于null
, attachRoot=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/