1、控件的宽高什么时候生效
当一个控件在一个容器中时,其设置的layout_width和layout_height会生效;
若一个控件不在一个容器中,layout_width和layout_height就不会生效;
2、inflate不同参数下不同情况
View inflate(int resource, ViewGroup root, boolean attachToRoot)
作用:Inflate a new view hierarchy from the specified xml resource.
参数说明:
①resource是要加载的布局id
②root是布局将插入到的 ViewGroup
③attachToRoot表示是否在inflate方法生效后将布局附加到ViewGroup上
④返回的View:inflate会将加载的布局文件解析成一个View DOM树,最顶层的View即为根视图,也就是返回的View
不同参数下的情况:
①如果root为null,布局的layout_width和layout_height会失效,attachToRoot也无效。
当通过addView(View)将这个宽高失效的View添加到一个容器中时,容器内部,会调用generateDefaultLayoutParams()生成一个LayoutParams赋值给这个View。
②如果root不为null,attachToRoot设为true,则会将加载的布局附加到root布局中。
③如果root不为null,attachToRoot设为false,布局不会附加到root布局中,但布局文件最外层的View所有layout属性(LayoutParams?)会根据layout_width和layout_height等进行设置,当该View被添加到一个容器当中时(addView、碎片的添加等),这些layout属性会自动生效。
④在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。
问:LayoutParams、generateDefaultLayoutParams()等是什么?
3、视图层次
一个Activity页面有一个顶级View叫做DecorView,DecorView中包含一个竖直方向的LinearLayout,LinearLayout由两部分组成,第一部分是标题栏,第二部分是内容栏,内容栏是一个FrameLayout,我们在Activity中调用setContentView就是将View添加到这个FrameLayout中
4、获得LayoutInflater的三种方法
在一个活动中:直接调用getLayoutInflater()
有context,调用LayoutInflater.from(context)
或(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
这三者其实都是调用的(LayoutInflater)context.getSystemService()
参考:http://www.cnblogs.com/androidez/archive/2013/07/01/3164729.html
5、findViewById()与inflate()
今天想要在一个碎片里调用findViewById(),发现不可以,查了一下资料,发现只可以在一个活动中直接调用,或用一个View对象调用(自定义布局里出现过),但二者也是有点区别的。
在Activity中直接调用Activity.findViewById()
或者有一个View对象,调用View.findViewById()
这二者其实都是用的View的findViewById()
参考:http://blog.csdn.net/breezylee2009/article/details/38580991
Acitivity中的findViewById
View findViewById(int id)
Finds a view that was identified by the id attribute from the XML that was processed in onCreate(android.os.Bundle).
View中的findViewById
View findViewById(int id)
Look for a child view with the given id.
//根据指定的id找到View的子(孙?)视图(依据View DOM树)
这两个api其实揭示了一个问题:没有在Activity的onCreate()方法中导入布局文件的控件是无法在Activity中产生实例。(有说控件不在当前Activity所在的窗口的,有说个已经载入的界面,也有可能是setContentView中载入的布局,待验证究竟是什么情况,因为后来引入的布局该怎么办的)
stack overflow上有一句话:
getActivity().findViewById() looks for the id you provide as parameter in the hierarchy of views of the Activity
感觉很有道理,id要是Activity视图层次中的控件的id
解决方法:root参数为null的inflate()在这里就起作用了(或者attachToRoot为false),inflate()加载控件所在的布局文件,却不将布局添加到Activity窗口中,同时返回布局文件的根视图,这个根视图就可以用来获得子视图的实例了:
View view = getLayoutInflater().inflate(R.layout.xxx,null);
Button button = (Button)view.findViewById(R.id.button);
小总结:
inflate()用来实例化布局文件的根视图;
findViewById()用父视图来实例化子视图