Android-LayoutInflater分析

来源:互联网 发布:同花顺软件k线图 编辑:程序博客网 时间:2024/06/09 17:22

作用

1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入。2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。

三种实例方式

1. LayoutInflater inflater = getLayoutInflater();//调用Activity的getLayoutInflater()2. LayoutInflater inflater = LayoutInflater.from(context);3. LayoutInflater inflater =  (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);其实,这三种方式本质是相同的,从源码中可以看出:它其实调用 context.getSystemService()。

四种调用方式

1. public View inflate(int resource, ViewGroup root)2. public View inflate(int resource, ViewGroup root, boolean attachToRoot)3.public View inflate(XmlPullParser parser, ViewGroup root)4.public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

inflate方法

inflate方法的主要作用就是将xml转换成一个View对象,用于动态的创建布局。

inflate方法有三个参数,分别是:

1.resource 布局的资源id2.root 填充的根视图3.attachToRoot 是否将载入的视图绑定到根视图中

具体分析:

具体分析:1.若我们采用convertView = inflater.inflate(R.layout.item_list, null);方式填充视图,item布局中的根视图的layout_XX属性会被忽略掉,然后设置成默认的包裹内容方式.分析:   Inflate(resId , null )不能正确处理宽和高是因为:layout_width,layout_height是相对了父级设置的,必须与父级的LayoutParams一致。而此temp的getLayoutParams为null2. 如果我们想保证item的视图中的参数不被改变,我们需要使用convertView = inflater.inflate(R.layout.item_list, parent,false);这种方式进行视图的填充.分析:可以看出完美的显示了宽和高。因为temp.setLayoutParams(params)。这个params正是root.generateLayoutParams(attrs);得到的。setContentView()与LayoutInfalter.inflate()的区别 setContentView()一旦调用,就会立即显示UI. 而LayoutInfalter.inflate()只是把布局转换成对应的View对象,不会立即显示,只有需要的时候再显示出来。

简单实例分析

首先新建一个项目,新建两个布局文件如下:
activity_main.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" >    <TextView         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="这是父视图"/></LinearLayout>

activity_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>

第一种方式:(很简单不做解释)

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // setContentView(R.layout.activity_main);        // 第一种方式        View childView = getLayoutInflater().inflate(R.layout.activity_main,                null);        setContentView(childView);    }}

第二种实现方式:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // setContentView(R.layout.activity_main);        // 第二种方式         ViewGroup parentView = (ViewGroup)getLayoutInflater().inflate(R.layout.activity_main, null);         View childView = getLayoutInflater().inflate(R.layout.activity_child,parentView);         setContentView(childView);    }}

结果如下:
这种方式的输出结果和inflate(view,root,true)是一致的;

第三种实现方式:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // setContentView(R.layout.activity_main);        // 第三种方式         ViewGroup parentView = (ViewGroup)getLayoutInflater().inflate(R.layout.activity_main, null);         View childView = getLayoutInflater().inflate(R.layout.activity_child,parentView,false);         setContentView(childView);    }}

结果如下:
==方式一中的效果

从以上我们可以得知:

只要inflate(view,root,attachToRoot)中root为null或者attachToRoot为false有一个成立的话,最后都会只显示当前子视图

我们可以对上面Activity代码进行修改,手动将子视图添加到父视图中。如下:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // setContentView(R.layout.activity_main);         ViewGroup parentView = (ViewGroup)getLayoutInflater().inflate(R.layout.activity_main, null);         View childView = getLayoutInflater().inflate(R.layout.activity_child,null,false);         parentView.addView(childView);         setContentView(parentView);    }}

结果如下:
略有不同


附录知识点

另外getSystemService()是Android很重要的一个API,它是Activity的一个方法,根据传入的NAME来取得对应的Object,
然后转换成相应的服务对象。以下介绍系统相应的服务。

传入的Name 返回的对象 说明 WINDOW_SERVICE WindowManager 管理打开的窗口程序 LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态 POWER_SERVICE PowerManger 电源的服务 ALARM_SERVICE AlarmManager 闹钟的服务 NOTIFICATION_SERVICE NotificationManager 状态栏的服务 KEYGUARD_SERVICE KeyguardManager 键盘锁的服务 LOCATION_SERVICE LocationManager 位置的服务,如GPS SEARCH_SERVICE SearchManager 搜索的服务 VEBRATOR_SERVICE Vebrator 手机震动的服务 CONNECTIVITY_SERVICE Connectivity 网络连接的服务 WIFI_SERVICE WifiManager Wi-Fi服务 TELEPHONY_SERVICE TeleponyManager 电话服务

示意代码:

LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));//EditText editText = (EditText)findViewById(R.id.content);// errorEditText editText = (EditText)view.findViewById(R.id.content);

对于上面代码,指定了第二个参数 ViewGroup root,当然你也可以设置为 null 值。
注意:
·inflate 方法与 findViewById 方法不同;
·inflater 是用来找 res/layout 下的 xml 布局文件,并且实例化;
·findViewById() 是找具体 xml 布局文件中的具体 widget 控件(如:Button、TextView 等)。


0 0
原创粉丝点击