Android学习笔记之View(一):LayoutInflater

时间:2022-06-20 17:50:52

使用LayoutInflater加载布局的两种方式:

第一种:

LayoutInflater
inflater=LayoutInflater.from(context);

inflater.inflate(R.layout.activity_main,null);

这也是最常用的一种。

第二种:

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

inflater.inflate(R.layout.activity_main,null);

实际上,第一种方式是吧第二种方式个封装起来了。

不管使用那个inflate()方法,最终都会转辗到LayoutInflater的如下方法的

public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {

synchronized (mConstructorArgs) {

final AttributeSet attrs = Xml.asAttributeSet(parser);

mConstructorArgs[0] = mContext;

View result = root;

try {

int type;

while ((type = parser.next()) != XmlPullParser.START_TAG &&

type != XmlPullParser.END_DOCUMENT) {

}

if (type != XmlPullParser.START_TAG) {

throw new InflateException(parser.getPositionDescription()

+ ": No start tag found!");

}

final String name = parser.getName();

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, attrs);

} else {

View temp = createViewFromTag(name, attrs);

ViewGroup.LayoutParams params = null;

if (root != null) {

params = root.generateLayoutParams(attrs);

if (!attachToRoot) {

temp.setLayoutParams(params);

}

}

rInflate(parser, temp, attrs);

if (root != null && attachToRoot) {

root.addView(temp, params);

}

if (root == null || !attachToRoot) {

result = temp;

}

}

} catch (XmlPullParserException e) {

InflateException ex = new InflateException(e.getMessage());

ex.initCause(e);

throw ex;

} catch (IOException e) {

InflateException ex = new InflateException(

parser.getPositionDescription()

+ ": " + e.getMessage());

ex.initCause(e);

throw ex;

}

return result;

}

}

  

LayoutInflater主要是通过Android的pull解析方式来解析布局文件的。

 
 

那么接下来我们再定义一个布局文件,给它取名为button_layout.xml,代码如下所示:

  1. <Button xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="wrap_content"  
  3.     android:layout_height="wrap_content"  
  4.     android:text="Button" >  
  5.   
  6. </Button>  

这个布局文件也非常简单,只有一个Button按钮而已。现在我们要想办法,如何通过LayoutInflater来将button_layout这个布局添加到主布局文件的LinearLayout中。运行结果如下:

Android学习笔记之View(一):LayoutInflater

 
 

 
 

当我们修改layout_width和layout_height属性后(比如改为300dp,300dp),再次运行,发现button大小并没有发生改变,是布局文件失效了吗?其实这里,无论怎么修改这两个属性都是没有的。因为layout_width和layout_height都是用来设置view在布局中的大小。

 
 

再来看一个布局

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="20dp"

android:layout_height="20dp"

android:background="#ff0000"

android:id="@+id/mainLayout">

</RelativeLayout>

在onCreate方法中执行如下操作:

Protected void onCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

运行结果如下

Android学习笔记之View(一):LayoutInflater

为什么这里的layout_width和layout_height属性又起作用了,那是因为在setContentView()方法中,Android会自动在布局文件最外层加一个FrameLayout,所以这里的layout_width和layout_height属性才有用。

那么我们来证实一下吧。修改onCreate方法

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mainLayout = (LinearLayout) findViewById(R.id.main_layout);

ViewParent viewParent = mainLayout.getParent();

Log.d("TAG", "the parent of mainLayout is " + viewParent);

}

运行结果如下

Android学习笔记之View(一):LayoutInflater