Android那些疑惑(2)-LayoutInflater中inflate方法参数的意义

LayoutInflater

Instantiates a layout XML file into its corresponding objects. It is never used directly. Instead, use {@link android.app.Activity#getLayoutInflater()} or {@link Context#getSystemService} to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on .
把一个xml布局文件实例化成一个对应的对象View.这个类不会被直接使用。我们可以通过Activity的方法getLayoutInflater()或者Context中的getSystemService(Context.LAYOUT_INFLATER_SERVICE)来获取一个LayoutInflater实例,这个实例和当前Context绑定在一起,而且根据你当前运行设备正确的被配置。

Inflate方法

/**
*参数resource,这个不多说,布局文件的资源id
*参数root,父控件
*参数attachToRoot,是否加载到父控件
**/
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot);

几种用法

下面是我定义的一个简单布局layout_test


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="40dp"
    android:layout_height="40dp">
RelativeLayout>

一个简单的TestActivity

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewGroup root = findViewById(R.id.content);
        View child;
        //1.child=getLayoutInflater().inflate(R.layout.layout_test,null);
        //2.child=getLayoutInflater().inflate(R.layout.layout_test,root,true);
        //3.child=getLayoutInflater().inflate(R.layout.layout_test,root,false);
        Log.d(getClass().getName(), child.toString());
    }
}

我们在Log.d这一行打个断点,观察child的具体情况

情况1

child=getLayoutInflater().inflate(R.layout.layout_test,null);

child实例化
这里写图片描述

child的布局属性mLayoutParams如下
Android那些疑惑(2)-LayoutInflater中inflate方法参数的意义_第1张图片

这里居然为null,我们回顾下layout_test.xml,我们不是定义了高和宽都是40dp吗?

情况2

child=getLayoutInflater().inflate(R.layout.layout_test,root,true);

child实例化
这里写图片描述
当attachToRoot为true的时候,子控件自动添加到父控件root中,返回父控件root.

通过mChildrens找到实际上的子控件,它的布局属性mLayoutParams如下
Android那些疑惑(2)-LayoutInflater中inflate方法参数的意义_第2张图片

这里我们定义的40dp根据密度转为120,而且是一个FrameLayout的LayoutParams,因为父类就是FrameLayout.

情况3

child=getLayoutInflater().inflate(R.layout.layout_test,root,false);

child实例化
这里写图片描述

当attachToRoot为false的时候,得到的child为RelativeLayout.

child的mLayoutParams
Android那些疑惑(2)-LayoutInflater中inflate方法参数的意义_第3张图片
宽高也正常,也是一个FrameLayout的LayoutParams

总结

情况一,你可以得到一个子控件,但是布局属性为空
情况二,你可以得到一个已经加入子控件的父控件,而且子控件的布局属性不为空。
情况三,你可以得到一个子控件,而且子控件的布局属性不为空,已经根据父控件设置好了,但是没有加入到父控件中。

应用场景

1.当布局文件不需要关注布局属性的时候,可以通过情况一来获取layout,如果你在布局文件定义了宽高,你可以通过
情况2,3来获取。
2.adapter中,不能通过情况二来获取layout,因为你会返回一个父控件

你可能感兴趣的:(Android疑惑录)