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

and*_*dig 165 android android-layout

我很难让LayoutInflater按预期工作,其他人也是如此:如何使用layoutinflator在运行时添加视图?.

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

and*_*dig 374

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

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

  • resource:要加载的XML布局资源的ID(例如R.layout.main_page)
  • root:可选视图是生成的层次结构的父级(如果attachToRoottrue),或者只是一个LayoutParams为返回的层次结构的根提供一组值的对象(如果attachToRootfalse.)
  • attachToRoot:膨胀的层次结构是否应附加到根参数?如果为false,则root仅用于为LayoutParamsXML中的根视图创建正确的子类.

  • 返回:膨胀层次结构的根视图.如果根供给和attachToRoottrue,这是根; 否则它是膨胀的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>
Run Code Online (Sandbox Code Playgroud)

添加到此容器中的是一个单独的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" />
Run Code Online (Sandbox Code Playgroud)

现在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

内容:调用LayoutInflater而不指定根导致调用忽略XML中的布局参数.主叫膨胀与根不相等nullattachRoot=true不装载布局参数,但再次返回根对象,其防止进一步的布局改变到加载的对象(除非则可以使用找到findViewById()).因此,您最有可能想要使用的调用约定是:

loadedView = LayoutInflater.from(context)
                .inflate(R.layout.layout_to_load, parent, false);
Run Code Online (Sandbox Code Playgroud)

为了解决布局问题,强烈建议使用布局检查器.

  • 很好的答案.已经在Android上工作了3年并且仍在计算中并且仍然需要从中学到一些东西. (19认同)
  • 容器的layout_width和layout_height设置为"match_parent"; 然后评论说"// result:layout_height = wrap_content layout_width = match_parent".我错过了吗? (5认同)

sea*_*ell 5

andig是正确的,因为LayoutInflater忽略您的layout_params的常见原因是未指定根。许多人认为您可以将null传递给root。对于某些情况(例如对话框),这是可以接受的,在这种情况下,创建时您无权访问root。但是,要遵循的一个好规则是,如果您具有root用户,则将其分配给LayoutInflater。

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

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