LayoutInflater解读

LayoutInflater解读

将一个布局XML文件实例化到相应的View对象。它从不直接使用。相反,使用
android.app.Activity#getLayoutInflater() 或Context#getSystemService检索已连接到当前Context对象的标准LayoutInflater实例,并为正在运行的设备正确配置。

获取LayoutInflater实例的方式:

1.使用LayoutInflater类中的inflate(@LayoutRes int resource, @Nullable ViewGroup root),inflater方法还有其他三个重载方法,其中涉及XmlPullParser暂不可使用,详见源码。

LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.layout_add_dialog, null);

2.在Activity中使用getLayoutInflater()

LayoutInflater inflater=getLayoutInflater(); 

3.系统推荐使用context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);

LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

LayoutInflater类源码解读:

//两个构造方法

/**
 * 创建一个与特定context关联的新的LayoutInflater实例
 *
 * 应用程序几乎总是希望使用context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 * 
 */
protected LayoutInflater(Context context) {
    mContext = context;
}

/**
 * 创建一个新的LayoutInflater实例,它是现有的一个LayoutInflater的副本,
 * 可以选择它的上下文发生了变化,用于实现cloneInContext
 * 
 * @param original The original LayoutInflater to copy.
 * 
 * @param newContext The new Context to use.
 */
protected LayoutInflater(LayoutInflater original, Context newContext) {
    mContext = newContext;
    mFactory = original.mFactory;
    mFactory2 = original.mFactory2;
    mPrivateFactory = original.mPrivateFactory;
    setFilter(original.mFilter);
}

/**
 * 从给定的上下文获得LayoutInflater对象
 */
public static LayoutInflater from(Context context) {
    LayoutInflater LayoutInflater =
            (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (LayoutInflater == null) {
        throw new AssertionError("LayoutInflater not found.");
    }
    return LayoutInflater;
}

/**
 * 创建一个现有的LayoutInflater对象的副本,并使用该副本指向一个不同的Context对象。
 * 这是使用ContextThemeWrapper来创建一个新的LayoutInflater,以便与新的上下文主题一起使用。
 */
public abstract LayoutInflater cloneInContext(Context newContext);

//inflate()方法重载

/**
 * Inflate a new view hierarchy from the specified xml resource.
 * Throws InflateException if there is an error.
 * 
 * @param resource ID for an XML layout resource to load (e.g R.layout.main_page)
 * 
 * @param root 可选视图作为生成的层次结构的父类。
 * 
 * @return inflated的层次结构的根视图。如果提供了root值,那么这就是根视图;
 * 否则,它就是inflated的XML文件的root。
 */
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
    return inflate(resource, root, root != null);
}

/**
 * Inflate a new view hierarchy from the specified xml node. 
 * Throws InflateException if there is an error.
 * 
 * 出于性能方面的原因, view inflation严重依赖于在构建时进行的XML文件的预处理。
 * 因此,目前不可能在运行时使用XmlPullParser在一个纯XML文件上使用LayoutInflater。 
 * 
 * @param parser 包含视图层次结构描述的XML dom节点。
 * 
 * @param root 可选,视图作为生成的层次结构的父类。
 * 
 * @return inflated的层次结构的根视图。如果提供了root值,那么这就是根视图;
 * 否则,它就是inflated的XML文件的root。
 */
public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
    return inflate(parser, root, root != null);
}

/**
 * Inflate a new view hierarchy from the specified xml resource. 
 * Throws InflateException if there is an error.
 * 
 * @param resource ID for an XML layout resource to load (e.g R.layout.main_page)
 * 
 * @param root 可选,如果attachToRoot值为true,视图是生成的层次结构的父类
 * 如果attachToRoot值为false,则是一个为返回的层次结构提供一组LayoutParams值的对象
 * 
 * @param attachToRoot 是否应该将inflated的层次结构附加到根参数上。
 * 如果是false,根只用于为XML中的根视图创建正确的LayoutParams的子类。
 * 
 * @return inflated的层次结构的根视图。如果提供了root,而attachToRoot是正确的,那么这就是根;
 * 否则它就是inflated的XML文件的根。
 */
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
    final Resources res = getContext().getResources();
    if (DEBUG) {
        Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                + Integer.toHexString(resource) + ")");
    }

    final XmlResourceParser parser = res.getLayout(resource);
    try {
        return inflate(parser, root, attachToRoot);
    } finally {
        parser.close();
    }
}

/**
 * Inflate a new view hierarchy from the specified XML node.
 * Throws InflateException if there is an error.
 * 
 * 出于性能方面的原因, view inflation严重依赖于在构建时进行的XML文件的预处理。
 * 因此,目前不可能在运行时使用XmlPullParser在一个纯XML文件上使用LayoutInflater。
 * 
 * @param parser 包含视图层次结构描述的XML dom节点。
 * 
 * @param root 可选,如果attachToRoot值为true,视图是生成的层次结构的父类,
 * 或者只是一个为返回的层次结构提供一组LayoutParams值的对象(如果attachToRoot值为false)。
 * 
 * @param attachToRoot 是否应该将inflated的层次结构附加到根参数上。
 * 如果是false,根只用于为XML中的根视图创建正确的LayoutParams的子类。
 * 
 * @return inflated的层次结构的根视图。如果提供了root,而attachToRoot是正确的,那么这就是根;
 * 否则它就是inflated的XML文件的根。
 */
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
    synchronized (mConstructorArgs) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");

        final Context inflaterContext = mContext;
        final AttributeSet attrs = Xml.asAttributeSet(parser);
        Context lastContext = (Context) mConstructorArgs[0];
        mConstructorArgs[0] = inflaterContext;
        View result = root;
        ...

        return result;
    }
}

Activity中定义了这样的方法

/**
 * Convenience for calling android.view.Window#getLayoutInflater
 */
@NonNull
public LayoutInflater getLayoutInflater() {
    return getWindow().getLayoutInflater();
}

Window类中的有关方法定义

/**
 * 快速访问该窗口从其上下文检索其LayoutInflater实例
 *
 * @return LayoutInflater The shared LayoutInflater.
 */
@NonNull
public abstract LayoutInflater getLayoutInflater();

猜你喜欢

转载自blog.csdn.net/sinat_34383316/article/details/75267461