android inflate初探

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、视图层次


android inflate初探_第1张图片

一个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()用父视图来实例化子视图

你可能感兴趣的:(android)