做这个AA项目时,本着尽可能将不懂得东西搞明白的想法,我对于view
有了更深的理解,下面是我打的一个比方。
假设activity
是工人,那么这个工人开始工作时通过attach()
方法启动了一个phoneWindow
对象,这个对象就是一个窗户,然后有了窗户就应该装
一块玻璃,而installDecor()
方法就是得到玻璃的,这是一个DecorView
,在系统的视图树中,这是根视图,下面就是一个linearLayout
,然后在
这个LinearLayout
下面是两个FrameLayout
,其中一个下面直接放入一个TextView
,这个TextView
用于显示标题,另一个FrameLayout
下面再接一个LinearLayout
,而这个LinearLayout
就是我们真正开始放入内容的布局。然后有了窗户后我们应该贴窗花,因为这样才会显得有内容,那么,什么
是窗花呢?窗花就是各种控件,也就是在布局xml
中定义的各种控件,当然,有xml
方式就有代码的方式,大同小异。那么如何将窗花贴到玻璃上
呢?这里需要说明,你将窗花贴到玻璃上,并不是说直接贴在玻璃上,而是贴在一张纸上再贴在玻璃上,因为这样方便管理(包括撤销和添加的位
置等),这一点很重要,这也就意味着,显示出来的控件一定是贴在纸上的,不管是窗户上原来的纸还是你新创建的纸,同时,如果你要寻找到窗
花,可以通过findViewById()
方法来寻找到,但是如果你要对窗花进行修改和使用,那么这个窗花一定是要在纸上的,而且你找到的窗花一定要是
这个纸上的窗花,也就是在findViewById()
方法前加上view
来指定是哪张纸,也就是说这张纸一定要加载出来,比如,一下代码:
ViewGroup viewGroup1= (ViewGroup) LayoutInflater.from(this).inflate(R.layout.activity_main,null);
RelativeLayout r= (RelativeLayout) viewGroup1.findViewById(R.id.r);
Button b=new Button(this);
b.setText("b1");
r.addView(b);
setContentView(r);
这个代码是没有问题的,但是,如果将第一行代码删了,变成:
RelativeLayout r= (RelativeLayout) findViewById(R.id.r);
Button b=new Button(this);
b.setText("b1");
r.addView(b);
setContentView(r);
那么,就会报错,内容大概是调用addView(b)
方法的对象是空的。
那么纸是什么呢?纸其实就是view
,是通过LayoutInflater
的inflate()
方法生成的,同时这里还需要提一点,如果你想将一张纸上的窗花黏在另一
张纸上,那么,你首先需要将这个窗花从原来的纸上撕下来,然后再将这个窗花贴在另一张纸上,这里的撕就是原来纸调用removeView()
方法,
然后黏在另一张纸上,就是另一张纸调用addview()
方法,那么这样能实现什么呢?
1.动态的将布局呈现
2.将布局的一部分替换掉
3.实现类似侧滑菜单的效果
这里还要提一点,因为窗口的大小是有限的,所以可能你的纸上的控件没有显示完全,如果你将这个纸上边的控件清除再调整纸的位置,或者直
接通过调整纸的位置将纸上边的控件挤掉,来达到让这张纸完全显示的结果,那么这意味着什么呢?
意味着可以通过这种方式实现侧滑菜单的效果。
其实说到底,侧滑菜单的效果的实现实际上就是实现将布局的一部分替换掉和动态呈现布局的功能,要掌握替换布局和动态呈现布局的原理,并
且灵活运用。比如实现侧滑菜单就有几种方式,不过原理都是一样的,下面列举一下我的两种方式:
1.在主布局中就有侧滑时需要的布局,只是一开始不让它呈现出来(设置高度等属性),然后当点击时呈现出来(往往是通过替换掉原来呈现出来的控件)
2.在主布局中没有侧滑时需要的布局,当点击时让它自己动态加载出来,然后贴在相应的位置的纸上。
同时需要注意一下,setcontentView()
方法是将纸黏在玻璃上,那么这张纸是哪张纸呢?这张纸就是你传入的参数,比如下面两种代码的区别:
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
RelativeLayout r= (RelativeLayout) findViewById(R.id.r); RelativeLayout r= (RelativeLayout) findViewById(R.id.r);
TextView t1= (TextView) r.findViewById(R.id.t); TextView t1= (TextView) r.findViewById(R.id.t);
t1.setText("t1"); t1.setText("t1")
b.setText("b1"); b.setText("b1");
r.addView(b); r.addView(b);
setContentView(r); setContentView(R.layout.activity_main);
这两代码就是最后一行不同,左边的代码显示出来是一个内容为t1的TextView和B1的Button, 右边的代码显示出来的是只有一个内容为hello world的TextView
这也就说明了显示出来的内容就是你传入的纸的内容,有人可能觉得这是废话,但是你写代码的时候可能就会搞混了,所以在这里提出来,一定要记住。