在Android程序中,可以使用ViewStub来实现延时加载或者动态加载的效果,当用ViewStub进行布局时,在没有setVisibility或者inflate()时,会隐藏在页面中,而且不会实例化,这样的好处就是提高加载速度,当我们需要时再去加载,比较类似于java中的“懒加载”。
另一个需要注意的就是ViewStub在被实例化后,就变成了已经定义指向的布局了,ViewStub相当于“消失”了,再想隐藏布局就需要调用setVisibility来实现。
当然,光说不练假把式,先介绍ViewStub的其中一种用途,在listview中我们一般加载的是后台数据,但是如果后台空空如也,这时怎么办,总不能放个空白的页面给用户看吧,UI设计中其中一条重要准则就是对用户的交互做出响应,所以即使没有内容也要告诉用户没有东西的事实。在没有ViewStub的时候我们怎么做呢?当然是先将空白的效果先写上来,比如放一个图片表示没有东西,然后设置为隐藏,再判断的时候设为显示,这样听起来好像没有问题,可以实现,但是我们在布局中已经实例化了一张图片,无疑是会加重内存消耗的,于是我们采用ViewStub来进行加载。
<ViewStub
android:id="@+id/viewstub"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout="@layout/nullpoint" />
我们需要设置指向的布局,这里假设nullpoint是一个显示没有东西的imageview
ListView listView;
ArrayAdapter<String> adapter;
String[] arry = new String[]{"1"};
ViewStub viewStub;
listView = (ListView) findViewById(R.id.listView1);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,arry);
if (arry.length == 0) {
viewStub = (ViewStub) findViewById(R.id.viewstub);
View view = viewStub.inflate();
listView.setVisibility(View.GONE);
}else {
listView.setAdapter(adapter);
}
我们首先是加载listview,然后判断是否有值,没有值我们就加载viewstub中的内容,当然这个代码还可以优化咯,把listview也作为一个viewstub,我们先通过判断listview是否有值来考虑是否加载这个布局。
再看第二种用法,其实大同小异,都是延时加载的做法
上面这个图取自于网易云音乐,类似的效果还有很多,首先listviewitem正常显示,当我们点击末尾的按钮时,当前点击项会展开,额外多出一些功能,如果不用ViewStub,我们为每一个listviewitem加上一个这个布局,然后设为隐藏,如果一页显示20个item,势必会非常的卡顿。那么这样的布局怎么写呢?
我们进行自定义adapter,然后在listview的单个item布局中加上这个ViewStub,然后去监听item的点击事件,当点击时我们去实例化当前item的ViewStub,这样就能实现我们的效果了