轉自:http://www.ithao123.cn/content-10951307.html
我們在講一個定義好的佈局文件(xml)文件加載到界面上展現出來的時候,通常會用到LayoutInflater的inflate方法,細心的同學會發現這個方法有四種重載,分別是:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root);
public View inflate(XmlPullParser parser, @Nullable ViewGroup root);
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot);
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot);
下面是Android Studio下查看到的源碼即相關方法的參數說明:
-
/**
-
* Inflate a new view hierarchy from the specified xml resource. Throws
-
* {@link InflateException} if there is an error.
-
*
-
* @param resource ID for an XML layout resource to load (e.g.,
-
* <code>R.layout.main_page</code>)
-
* @param root Optional view to be the parent of the generated hierarchy.
-
* @return The root View of the inflated hierarchy. If root was supplied,
-
* this is the root View; otherwise it is the root of the inflated
-
* XML file.
-
*/
-
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
-
* {@link InflateException} if there is an error. *
-
* <p>
-
* <em><strong>Important</strong></em> For performance
-
* reasons, view inflation relies heavily on pre-processing of XML files
-
* that is done at build time. Therefore, it is not currently possible to
-
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
-
*
-
* @param parser XML dom node containing the description of the view
-
* hierarchy.
-
* @param root Optional view to be the parent of the generated hierarchy.
-
* @return The root View of the inflated hierarchy. If root was supplied,
-
* this is the root View; otherwise it is the root of the inflated
-
* XML file.
-
*/
-
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
-
* {@link InflateException} if there is an error.
-
*
-
* @param resource ID for an XML layout resource to load (e.g.,
-
* <code>R.layout.main_page</code>)
-
* @param root Optional view to be the parent of the generated hierarchy (if
-
* <em>attachToRoot</em> is true), or else simply an object that
-
* provides a set of LayoutParams values for root of the returned
-
* hierarchy (if <em>attachToRoot</em> is false.)
-
* @param attachToRoot Whether the inflated hierarchy should be attached to
-
* the root parameter? If false, root is only used to create the
-
* correct subclass of LayoutParams for the root view in the XML.
-
* @return The root View of the inflated hierarchy. If root was supplied and
-
* attachToRoot is true, this is root; otherwise it is the root of
-
* the inflated XML file.
-
*/
-
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
-
* {@link InflateException} if there is an error.
-
* <p>
-
* <em><strong>Important</strong></em> For performance
-
* reasons, view inflation relies heavily on pre-processing of XML files
-
* that is done at build time. Therefore, it is not currently possible to
-
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
-
*
-
* @param parser XML dom node containing the description of the view
-
* hierarchy.
-
* @param root Optional view to be the parent of the generated hierarchy (if
-
* <em>attachToRoot</em> is true), or else simply an object that
-
* provides a set of LayoutParams values for root of the returned
-
* hierarchy (if <em>attachToRoot</em> is false.)
-
* @param attachToRoot Whether the inflated hierarchy should be attached to
-
* the root parameter? If false, root is only used to create the
-
* correct subclass of LayoutParams for the root view in the XML.
-
* @return The root View of the inflated hierarchy. If root was supplied and
-
* attachToRoot is true, this is root; otherwise it is the root of
-
* the inflated XML file.
-
*/
-
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;
-
try {
-
// Look for the root node.
-
int type;
-
while ((type = parser.next()) != XmlPullParser.START_TAG &&
-
type != XmlPullParser.END_DOCUMENT) {
-
// Empty
-
}
-
if (type != XmlPullParser.START_TAG) {
-
throw new InflateException(parser.getPositionDescription()
-
+ ": No start tag found!");
-
}
-
final String name = parser.getName();
-
if (DEBUG) {
-
System.out.println("**************************");
-
System.out.println("Creating root view: "
-
+ name);
-
System.out.println("**************************");
-
}
-
if (TAG_MERGE.equals(name)) {
-
if (root == null || !attachToRoot) {
-
throw new InflateException("<merge /> can be used only with a valid "
-
+ "ViewGroup root and attachToRoot=true");
-
}
-
rInflate(parser, root, inflaterContext, attrs, false);
-
} else {
-
// Temp is the root view that was found in the xml
-
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
-
ViewGroup.LayoutParams params = null;
-
if (root != null) {
-
if (DEBUG) {
-
System.out.println("Creating params from root: " +
-
root);
-
}
-
// Create layout params that match root, if supplied
-
params = root.generateLayoutParams(attrs);
-
if (!attachToRoot) {
-
// Set the layout params for temp if we are not
-
// attaching. (If we are, we use addView, below)
-
temp.setLayoutParams(params);
-
}
-
}
-
if (DEBUG) {
-
System.out.println("-----> start inflating children");
-
}
-
// Inflate all children under temp against its context.
-
rInflateChildren(parser, temp, attrs, true);
-
if (DEBUG) {
-
System.out.println("-----> done inflating children");
-
}
-
// We are supposed to attach all the views we found (int temp)
-
// to root. Do that now.
-
if (root != null && attachToRoot) {
-
root.addView(temp, params);
-
}
-
// Decide whether to return the root that was passed in or the
-
// top view found in xml.
-
if (root == null || !attachToRoot) {
-
result = temp;
-
}
-
}
-
} catch (XmlPullParserException e) {
-
InflateException ex = new InflateException(e.getMessage());
-
ex.initCause(e);
-
throw ex;
-
} catch (Exception e) {
-
InflateException ex = new InflateException(
-
parser.getPositionDescription()
-
+ ": " + e.getMessage());
-
ex.initCause(e);
-
throw ex;
-
} finally {
-
// Don't retain static reference on context.
-
mConstructorArgs[0] = lastContext;
-
mConstructorArgs[1] = null;
-
}
-
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-
return result;
-
}
-
}
根據以上源碼我們會發現,重載的四個方法歸根結底最後調用的都是這個方法:
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)
該方法和以下方法的區別在於下面的方法根據提供的resource來獲得相應的parser,然後再調用上面的方法。
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
所以我們主要來分析這個方法。參數詳解:
第一個參數:int resource,表示需要加載佈局文件的id,意思是需要將這個佈局文件中加載到Activity中來操作;
第二個參數:ViewGroup root,表示需要附加到resource資源文件的根控件。說明:調用inflate方法後會得到一個View對象,root參數就是接收該 View對象的容器;
第三個參數:boolean attachToRoot, 表示是否把inflate得到的View對象添加到root中,該參數爲false時,表示不直接添加到root中;該參數爲true時,表示直接添加到root中;
下面同過具體代碼來說明:
activity_main.xml
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="fill_parent"
-
android:layout_height="fill_parent"
-
android:orientation="vertical">
-
<TextView
-
android:layout_width="fill_parent"
-
android:layout_height="wrap_content"
-
android:text="@string/hello" />
-
<FrameLayout
-
android:id="@+id/fl_container"
-
android:layout_width="match_parent"
-
android:layout_height="wrap_content">
-
</FrameLayout>
-
</LinearLayout>
inflate_view_layout.xml
-
<?xml version="1.0" encoding="utf-8"?>
-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width="match_parent"
-
android:layout_height="match_parent"
-
android:orientation="vertical">
-
<CheckBox
-
android:id="@+id/checkBox1"
-
android:layout_width="wrap_content"
-
android:layout_height="wrap_content"
-
android:text="@string/checkBox" />
-
</LinearLayout>
MainActivity.java
-
package com.rainmonth.inflatemethoddemo;
-
import android.support.v7.app.AppCompatActivity;
-
import android.os.Bundle;
-
import android.text.Layout;
-
import android.view.LayoutInflater;
-
import android.view.View;
-
import android.widget.FrameLayout;
-
public class MainActivity extends AppCompatActivity {
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.fl_container);
-
// 第三個參數設置爲false
-
View inflateView = LayoutInflater.from(this).inflate(R.layout.inflate_view_layout, frameLayout, false);
-
// 第三個參數設置爲true,默認爲true
-
// View inflateView = LayoutInflater.from(this).inflate(R.layout.inflate_view_layout, frameLayout, true);
-
}
-
}
第三個參數爲false時的運行結果如下:
此時,inflateView 對應的佈局內容並未呈現出來。
第三個參數爲true時的運行結果如下:
此時inflateView對應的佈局內容呈現出來了。由此可見第三個參數的作用就是是否把inflate出來的參數加入到root容器中,false時不添加;true時添加。
爲了驗證結論,我們在第三個參數爲false時在添加一下代碼:
frameLayout.addView(inflateView);
我們發現其現實結果同第三個參數設置爲true時是一樣的,所以我們的結論得到了驗證。