ViewStub

什么时候使用ViewStub?为什么使用?

需要控制某个View显示或者隐藏的话,会把需要的View写在布局上,然后通过View.GONE/View.InVisible设置可见性;这样虽然操作简单,但是还是耗费资源,因为即使view不可见,还是可以被父窗体控制,还是会被创建对象,还是会被实例化,还是会被设置属性。
Android.view.ViewStub是一个大小为0,默认不可见的控件,只有给它设置成了View.Visiable或者调用了inflate()才会填充布局资源,占用的资源少。推荐使用ViewStub;

基本介绍

ViewStub是一个不可见,大小为0的视图,可以在运行过程中延时加载布局资源;
当ViewStub被设置成可见,或者它的inflate()被调用的时候,布局资源才会被填充,然后ViewStub本身就会被填充起来的布局资源替换掉,它在视图树里面就不存在了,被填充的布局在替换ViewStub的时候会使用ViewStub的布局参数(LayoutParameters),如height,width等;也可以通过ViewStub的inflateId属性定义或者重写被填充布局资源的Id。

总结

o ViewStub引用布局时,使用layout属性,取值@layout/XXXX;

o InflateId表示给被引用布局的ID,也就是被控制显示或隐藏的布局的id;

o 如果不写inflateId的话,如果需要可以在被引用的布局中直接给出id属性;

o inflate()方法只能被调用一次,如果再调用会报异常信息,ViewStub must have a non null ViewGrounp ViewParent,
ViewStub使用inflate()将其引用的布局view展示出来之后,ViewStub本身就会从视图树里面被移除,此时ViewStub就获取不到它的父布局,而inflate()一上来就需要获取它的父布局,然后根据父布局是否为空再去执行具体的填充逻辑,如果一开始就是空,就会报出上面的错误。
所以如果inflate()之后如果还想调用ViewStub引用的布局view,就需要在调用inflate()的时候使用try–catch(),当catch到异常的时候调用setVisibility()设置ViewStub的View.Visible即可。

o ViewStub里面的setVisibility()里面也多次调用inflate(),这个时候为什么不会崩溃?
ViewStub的setVisibility()里面会先判断WeakReference类型的成员变量mInflatedViewRef是否为空,第一次调用setVisibility()的时候,mInflatedViewRef没有被初始化,所以为Null,这个时候就会走inflate,在inflate()里面创建起来的布局填充一个WeakReference弱引用,并且赋值给mInflatedViewRef,从而完成mInflateViewRef的初始化;
第二次调用setVisibility()的时候,mInflatedViewRef不是null,就会调用WeakReference的父类Reference里面的get()方法获取该引用指向的实体对象,也就是说通过get()拿到被填充的对象view,然后再走View的setVisibility()。

o ViewStub的inflate()只能被调用一次;
如果想控制/修改被填充布局里面的内容并重复显示被填充的view,就用try将viewStub.inflate()方法以及修改内容的代码包裹起来,并在catch里面setVisibility。

o 在xml中定义ViewStub结点的时候,内部不能包含其他节点,也就是说ViewStub是一个自闭和结点,如果一个布局/View想通过ViewStub显示,只能定义在单独的xml文件中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值