通过对inflate与 findViewById 方法的探究深度了解一下Android
来源:互联网 发布:租房月付软件 编辑:程序博客网 时间:2024/05/16 08:38
===================================================================
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。
具体作用:
1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。
LayoutInflater作用是将layout的xml布局文件实例化为View类对象。
注意:
·inflate方法与 findViewById 方法不同;
·inflater 是用来找 res/layout下的 xml 布局文件,并且实例化;
·findViewById() 是找具体 xml 布局文件中的具体 widget控件(如:Button、TextView 等)。
====================================================================
上述就是目前小编找到的最靠谱的说法了,但是讲的依然有一些小瑕疵,不够深入。
首先,小编认为.inflate方法与findViewById方法不是类似的,而是完全两个领域的方法,根本没有可比性。
其次,也是非常重要的一点是上述的最后一句话理解有误,暴露了对底层原理理解的偏差。
小编是这样理解的:我们可以把*.xml布局文件理解为“模板”,就像在学习Java时我们知道的,类是对象的“模板”一样。所以,就像Java的虚拟机会根据我们写的类实例化成一个个的对象一样,Android也会根据我们写的.xml文件实例化出View对象。而Android应用就是靠这一个个的View对象构建起庞大而复杂的APP的。所以,在Android的UI开发中,应时刻记得我们是在操作着一个个的View对象,而不是.xml文件,把对那些方法的理解联系到对象上。
inflate方法的作用就是根据.xml文件,实例化出一个对象来。如:
<LinearLayout android:id="@+id/test_linear" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
根据这个“模板”,系统会为我们实例化出一个包含了两个Button形子View对象的LinearLayout形的ViewGroup父对象,所以不知不觉之间,其实我们创建了起码3个对象。而这就是inflate方法的实际意义——生成对象。
再来看看findViewById,这个方法其实是基于父View对象进行的。比如说上面被实例化出来的LinearLayout对象,我们如果想找到它所包含的某个Button对象,就有可能用到findViewById方法。以识别Id的方式来查找子对象。所以findViewById的实际意义是——查找对象(不生成对象,而是找到它并返回它)。
下面小编就通过测试代码带大家理解一下Android这个平台的局部原理。
main_activity.xml:
<LinearLayout xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.testandroidview.MainActivity"><Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮1"/> <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2"/></LinearLayout>
activity_sub.xml:
<LinearLayout> xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.testcontentprovider2.MainActivity"><LinearLayout android:id="@+id/test_linear" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <Button android:id="@+id/sub_add" android:layout_width="wrap_content" android:layout_height="wrap_content"/></LinearLayout> </LinearLayout>
下面给出两个Activity代码,会在代码中伴随讲解原理
MainActivity.java
public class MainActivity extends Activity { Buttonbtn1; Buttonbtn2; Buttonbtn3; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = (Button)findViewById(R.id.btn1); btn2 = (Button)findViewById(R.id.btn2); btn3 = (Button)findViewById(R.id.btn3); btn1.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub System.out.println("MainActivity's btn1 pressed!"); } }); btn2.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub System.out.println("MainActivity's btn2 pressed!"); } }); btn3.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub Intentintent = new Intent(MainActivity.this, SubActivity.class); startActivity(intent); } }); }}
SubActivity.java 这个Activity是测试的关键
public class SubActivity extends Activity { Buttonbtn; @Override protectedvoid onCreate(Bundle savedInstanceState) { // TODOAuto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub); btn =(Button) findViewById(R.id.sub_add); btn.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub addTestView(); } }); } private voidaddTestView() { //找到当前Activity下的一个View容器,准备用这个容器去addView finalLinearLayout ll = (LinearLayout)findViewById(R.id.test_linear); //这里的动作就是寻找,因为整个布局的对象已经在setContentView(R.layout.activity_sub);代码执行完成后就已经实例化出来了,我们要找的LinearLayout就在这个大对象里,是它的一个子对象。 //渲染出即将被添加的View(下面就是另一个实例化操作) LayoutInflater li = LayoutInflater.from(this); finalLinearLayout view = (LinearLayout) li.inflate( R.layout.activity_main, null); //可见,即将被添加的View就是用的MainActivity的xml模板实例化出来的,这样就是为了测试该View下的按钮btn1btn2是否会与MainActivity中的按钮混淆(当然,我们可以预测到,如果混淆,那就说明我们的组件是"模板化"的,否则,我们的组件则是"对象化"的) ll.addView(view); //分别用两种不同的方法给即将被添加的View中的btn1和btn2添加点击事件 // 方法1 Button btn1= (Button) view.findViewById(R.id.btn1); btn1.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub System.out.println("SubActivity's btn1 pressed!"); } }); // 方法2 Button btn2= null; for (int i =0; i < view.getChildCount(); i++) { int id =view.getChildAt(i).getId(); if (id ==R.id.btn2) { btn2 =(Button) view.getChildAt(i); } } if (!(btn2== null)) { btn2.setOnClickListener(new View.OnClickListener() { @Override public voidonClick(View v) { // TODOAuto-generated method stub System.out.println("SubActivity's btn2 pressed!"); } }); } }}
之所以可以用方法2,是因为这里的父View即变量view是LinearLayout,而不仅仅是View,LinearLayout是继承自ViewGroup的,所以它可以getChild,如果是直接继承自View的子类是没有Child可言的
以上均测试完毕后不难总结出来:R.id.btn1这个int值(存在于R.java文件中)不是某个按钮的唯一标识,而是btn1按钮的"模板"的唯一标识,而我们可以通过xml模板在不同的地方产生不同的btn1对象,这些对象都是相互独立存在的,而我们用到R.id.btn1这个int值仅仅是在某地"寻找"btn1对象的时候用到的一个匹配工具
有哪里讲的不对的地方麻烦看客老爷们多多纠正,感激涕零。
还是那句话,每在某个角度了解了一些后,都会突然对Android感到陌生,感觉又重新认识了她一样。
附上源码:http://pan.baidu.com/s/1i31NK0l
- 通过对inflate与 findViewById 方法的探究深度了解一下Android
- Android inflate方法与 findViewById 方法区别
- inflate 方法与 findViewById方法的区别
- [Android]inflate方法与 findViewById 方法区别 | LayoutInflater的inflate函数用法详解
- [Android]inflate方法与 findViewById 方法区别 | LayoutInflater的inflate函数用法详解
- inflate方法与findViewById的区别
- inflate方法与findViewById的区别
- findViewById的问题和inflate(0方法
- 探究LayoutInflater的inflate()方法
- inflate与findViewById
- 关于android之LayoutInflater的inflate()方法和findViewById()方法
- 有关Fragment的getActivity().findViewById,以及inflate与 findViewById 区别、setContentView和inflate的区别!!!
- inflate和findViewById方法对比
- findViewById方法探究
- inflate, findViewById与setContentView的区别与联系
- inflate, findViewById与setContentView的区别与联系
- inflate, findViewById与setContentView的区别与联系
- android 中findViewById和inflate的使用区别
- 递归求n!c语言写的 环境vs2010
- Mybatis无实体类,以List<Map<String,Object>>方式返回
- 时间的使用,相加减
- N个数组中所有元素的排列组合(笛卡尔积)算法
- virtualbox安装多台虚拟机无法上网的问题
- 通过对inflate与 findViewById 方法的探究深度了解一下Android
- 面向接口编程详解(二)——编程实例
- 买水果-组合公式
- Linux学习笔记
- 699 - The Falling Leaves
- 【linux】内核中根据inode得到文件名
- 【M3U8】测试地址及android播放器
- 汽水瓶
- Tri Tiling - POJ 2663 递推