android-LayoutInflater的inflate方法详解
前面在使用Fragment的时候,我们通常都要重写他的onCreateView方法,这个方法的方法的使用如下:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1,container,false);
}
可以看到我们通常都是调用LayoutInflater的inflate方法来获得这个View的,但是传入的这些参数到底是干什么的呢?我们有必要去看看android源码是怎么实现的了:
从android官方API中我们可以看到LayoutInflater共有四个inflate方法:
这四个方法最终都会调用public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)这个方法,所以我们只需要看看这个方法源码就可以了:
这个方法的前面大半部分是通过XmlPullParser进行xml解析并且对解析的结果进行各种判断的,不是本方法的重点,我们仅看重要部分:
View temp; if (TAG_1995.equals(name)) { temp = new BlinkLayout(mContext, attrs); } else { temp = createViewFromTag(root, name, 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); } }
第10行首先会判断是否存在父视图,如果存在的话,则在16行获得子视图的布局参数,这里的attrs是通过XmlPullParser解析到的子视图资源文件中的xml标签所对应的set集合,第17行通过判断attachToRoot如果是false的话,则只将temp(是一个声明为View的局部变量)设置为子视图;
如果root非空,并且attachToRoot为true的话,则会将当前子视图添加到父视图中;
if (root != null && attachToRoot) { root.addView(temp, params); }如果root为空或者attachToRoot为false的话,则直接返回我们创建的temp
if (root == null || !attachToRoot) { result = temp; }
下面通过实例来看看传入不同的参数的效果:
定义parent.xml作为父视图:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fatherLinearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#00ff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是父视图"/> </LinearLayout>定义child.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" android:background="#ffff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="这是子视图"/> </LinearLayout>第一种方式:inflate(view,null)
public class LayoutInflaterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View childView = getLayoutInflater().inflate(R.layout.child, null); setContentView(childView); } }输出结果:
第二种方式:inflate(view,root)
public class LayoutInflaterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup parentView = (ViewGroup) getLayoutInflater().inflate(R.layout.parent, null); View childView = getLayoutInflater().inflate(R.layout.child, parentView); setContentView(childView); } }
输出结果:
这种方式的输出结果和inflate(view,root,true)是一致的;
第三种方式:inflate(view,root,false)
public class LayoutInflaterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup parentView = (ViewGroup) getLayoutInflater().inflate(R.layout.parent, null); View childView = getLayoutInflater().inflate(R.layout.child, parentView,false); setContentView(childView); } }输出结果:
可以看到这种方式和root==null的显示效果是一样的,这一点从源码中也能找到答案:
if (root == null || !attachToRoot) { result = temp; }只要inflate(view,root,attachToRoot)中root为null或者attachToRoot为false有一个成立的话,最后都会只显示当前子视图,我们可以对上面Activity代码进行修改,手动将子视图添加到父视图中:
public class LayoutInflaterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup parentView = (ViewGroup) getLayoutInflater().inflate(R.layout.parent, null); View childView = getLayoutInflater().inflate(R.layout.child, null,false); parentView.addView(childView); setContentView(parentView); } }输出结果:
注意这种方式和inflate()方式将子视图加入父视图显示的效果是不一样的;这种方式是以父视图为主,inflate方式是以子视图为主;