ViewStub是一个有利于节省布局资源的控件,当布局中一些元素不需要一开始就加载的时候,我们可以让他先处于“休眠”状态,等需要时再加载上来。之前一直没有接触使用过,最近项目中遇到一个场景突然可以用。
场景是:进入页面后会搜索本地音乐,如果没有本地音乐,那么将显示一个占位图。这是一个非常常见的场景,之所以想到用ViewStub,是因为占位图非常之大,虽然不至于撑破你的内存,但是能省就省吧,更何况对于大多数用户来说,根本就看不到这个图。
ViewStub特点:
ViewStub 在没被加载之前,是一个很空的View,空到连大小都没有
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(0, 0);
}
infalte 会把指向的 layout 加载到自己所在的parent上,并移除自己(传说中的千斤顶?)
所以ViewStub非常适合用于节省布局的消耗
基本使用:
在布局中:
<ViewStub
android:id="@+id/rl_nomusic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/module_tool_music_no_music"
android:visibility="gone"/>
layout 是必须要指定的。这里的 visibility 无论设置什么最后都会是 GONE
源码中你会看到
public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ViewStub, defStyleAttr, defStyleRes);
mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
a.recycle();
setVisibility(GONE); //就是这里
setWillNotDraw(true);
}
在代码中,你可以调用 viewstub.inflate() 来加载它
当然更简单的就是 viewstub.setVisibility() 内部会处理
public void setVisibility(int visibility) {
if (mInflatedViewRef != null) {
View view = mInflatedViewRef.get();
if (view != null) {
view.setVisibility(visibility);
} else {
throw new IllegalStateException("setVisibility called on un-referenced view");
}
} else {
super.setVisibility(visibility);
if (visibility == VISIBLE || visibility == INVISIBLE) {
inflate(); //基本知识:VISIBLE 和 INVISIBLE 都是被加载的
}
}
}
你可能关心的:
viewstub 中的 view 需要被 infalte() 之后才能通过 findviewbyid 去找到,那么如果需要设置监听就在再 setVisibility() 之后?那也太蠢了吧!
本来想模仿 view.post() 写一个 runable 在 setVisibility() 之后跑
结果 VIewStub 是 final 的(绝望)
结果看源码的时候(总共才300行)发现。。 原来人家是有监听给你的
setOnInflateListener()
僵硬- -
转眼间从事安卓开发已经一年多了,期间写了无数的自定义控件,各种复杂的交互动画,因为项目需要也自学了OpenGLES(《图片合成器》 - 已离职),但一直没有在GitHub上分享过自己的代码,今天第一篇简书算是一个起点,希望能有帮助,有什么问题也欢迎留言,共同学习,共同进步。
网友评论