它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如 Button、TextView等)。
作用就是:找布局文件,并动态加载.
public void OnMenu(View view){
// 获取自定义的菜单布局文件
View popupWindow_view = getLayoutInflater().inflate(R.layout.menu, null,false);
// 创建PopupWindow实例,设置菜单宽度和高度为包裹其自身内容
popupWindow = new PopupWindow(popupWindow_view, ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT, true);
//设置菜单显示在按钮的下面
popupWindow.showAsDropDown(findViewById(R.id.btn_menu),0,0);
// 点击其他地方消失
popupWindow_view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//如果菜单存在并且为显示状态,就关闭菜单并初始化菜单
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
popupWindow = null;
}
return false;
}
其中View popupWindow_view = getLayoutInflater().inflate(R.layout.menu, null,false);
是三个参数的情况,
inflate()方法官方描述如下:
假如root设置为null或者root!=nul但attachToRoot设置为false,则这个xml加载出来的view不会挂载到别的视图节点上去;
当root!=null并且attachToRoot设置为true时,就会挂载上去,return为root
当 root!=nul但attachToRoot设置为false时,这个root用来view生成正确的params布局参数来match root。
这里的inflate(int resource, ViewGroup root, boolean attachToRoot)方法包含了三个参数:
resource代表要加载布局的id,
root代表inflate对象所依托的父容器,
boolean attachToRoot表示是否需要将inflate的View依托到root中。
inflate还有两个参数的方法,inflate(int resource, ViewGroup root)
其实也是调用了上面的方法
关于root和attachToRoot两个参数存在着如下逻辑:
1、root为空,attachToRoot失去意义,无论它是true还是false,都不会将layout加载到root中,只是返回createViewFromTag()方法所加载的view;
2、如果root不为空,attachToRoot设为true,则会给layout指定一个父布局root(root.addView(temp, params))。
3、如果root不为空,attachToRoot设为false,则只是将root的布局参数设置给要加载的layout(temp.setLayoutParams(params)),这也是最常用的一种情况。当该layout被添加到父view当中时,这些layout属性会自动生效。
当前实例中,使用了inflate,(隐形膨胀),隐性摆放在view里,inflate()前只是获得控件,但没有大小没有在View里占据空间,inflate()后有一定大小,只是出于隐藏状态,相当于动态加载这个布局文件.
有三个参数,
第一个是R.layout.menu,这是view的layoutID,(res/layout/menu.xml),其实就是当前这个xml的名字,表示要加载这个xml了;
第二个参数是null, 第三个参数失去意义,不会将layout加载到root中;
第三个参数的false,说明这个xml加载出来的view不会挂载到父容器上.