LayoutInflater用来实例化XML布局为View对象,使用LayoutInflater方式可以动态加载布局,LayoutInflater实例对象调用inflate方法从指定的XML资源中填充一个新的视图:
public View inflate (int resource, ViewGroup root,[boolean attachToRoot]) |
从指定的XML资源中填充一个新的视图 |
参数resource:将要加载的XML布局id,例如R.layout.list_item 参数root:父视图,可选项,一般为Null 重载参数attachToRoot:是否立即显示填充后的父视图,false表示使用addView()方法手动添加到父视图,true表示自动添加到父视图,如果为true后,再使用addView()方法添加,程序会报错,要求先removeView()掉子布局 |
在XML布局文件中,描述View对象的宽高属性可以使用android:layout_width和android:layout_height,以及android:width和android:height;其中android:layout_width和android:layout_height属性必须位于父容器(父布局)中才会生效,android:width和android:height属性必须在android:layout_width和android:layout_height属性生效且为wrap_content时才有用,起到微调宽高的作用。
inflate(int resource,null,null)的作用是将resource实例化成view对象并返回。 |
inflate(int resource,ViewGroup root,null/false)的作用是根据root布局(父布局)设置resource的layout_width和layout_height属性后,再将resource实例化成view对象且返回。 |
inflate(int resource,ViewGroup root,true)的作用是根据root布局(父布局)设置resource的layout_width和layout_height属性后,将resource填充到root布局(父布局)中,最后将填充完毕的root布局实例化成view对象且返回。 |
inflate(int resource,null,null)由于没有指定root布局视图,resource实例化成view对象后,resource的最外层布局layout_width和layout_height属性是无效的,所以view对象的宽高将是默认值wrap_content。
inflate(int resource,ViewGroup root,null/false)方式指定了root布局视图,resource实例化成view对象时,将会根据root布局视图来设置resource的最外层布局layout_width和layout_height属性,最后返回设置完宽高属性的resource实例化view对象,第二种方法和第一种的都是返回resource的实例view对象,区别就是第一个宽高属性无效,第二个宽高属性有效,第一种和第二种方式都需要在程序逻辑后面使用addView()方法来手动填充view对象到root父布局视图中,才能显示出来。
inflate(int resource,ViewGroup root,true)方式中的参数true表示立即将resource填充到root布局视图中,并将填充后的root布局视图实例化为view对象返回,此时root视图中可以看到resource视图,无需使用addView()方法手动填充。
可以通过三种方式获取LayoutInflater实例对象:
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View myView = inflater.inflate(R.layout.main, null); |
LayoutInflater inflater = LayoutInflater.from(context); View myView = inflater.inflate(R.layout.main, null); |
LayoutInflater inflater = getLayoutInflater(); View myView = inflater.inflate(R.layout.main, null); |
第一种方式使用在拥有上下文Context对象时,调用getSystemService()方法获取Inflater对象,这也是最为底层的实现方法;第二种方式使用LayoutInflater类的静态方法from(),from()方法也需要参数context,其实就是第一种方法的简单封装;第三种方式调用当前Activity实例的getLayoutInflater()方法,其实也还是第一种方式的变体,只是省去了获得context对象的过程,被封装了,使用更简单。
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/otherOneItem" android:title="OtherOne"/> <item android:id="@+id/otherTwoItem" android:title="OtherTwo"/> <item android:id="@+id/otherThreeItem" android:title="OtherThree"/> </menu> |
MenuInflater用来加载menu布局文件,对应每个Activity界面都有一个属于自己的menu,可以使用当前Activity实例的getMenuInflater()方法获取针对menu的inflater对象,该inflater对象调用inflate()方法加载res\menu目录下的menu布局XML文件,将其填充到当前activtiy的menu菜单里,该inflate()方法并不返回任何实例化view对象,也就是说,你不能动态调整menu菜单,只能静态在XML文件中一次性加载完成。
@Override public boolean onCreateOptionsMenu(Menu menu) { this.getMenuInflater().inflate(R.menu.menu_layout,menu); return super.onCreateOptionsMenu(menu); } |
当前Activity对象的menu被创建时会回调当前Activity的onCreateOptionsMenu(Menu menu)方法,可以在该方法体中使用getMenuInflater().inflate(R.menu.menu_layout,menu)方法来完成对menu布局的填充。
@Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.otherOneItem: Toast.makeText(OtherActivity.this,"OtherOneItem",Toast.LENGTH_SHORT).show(); break; case R.id.otherTwoItem: Toast.makeText(OtherActivity.this,"OtherTwoItem",Toast.LENGTH_SHORT).show(); break; case R.id.otherThreeItem: Toast.makeText(OtherActivity.this,"OtherThreeItem",Toast.LENGTH_SHORT).show(); break; default: break; } return super.onOptionsItemSelected(item); } |
当menu中的item被点击时,将回调Activity对象的onOptionsItemSelected(MenuItem item)方法,可以在该方法体中使用switch逻辑判断不同的item对应不同的处理逻辑。