在开发APP的时候,经常会遇到需要在运行时动态地判断显示哪个View或布局。通常做法是把所有可能都写上面,设可见性为View.GONE,然后在代码中动态地修改它的可见性。这样做的优点是逻辑简单、控制灵活。但是缺点是耗费资源。虽然把View的可见性设为View.GONE,但是在inflate布局的时候,View还是会被inflate的,也就是说仍然会创建对象,这会耗费内存等资源。
推荐使用ViewStub,它是一个轻量级的View,看不见又不占用布局位置,且占用资源非常小的控件。
可以为ViewStub指定一个布局,在inflate布局的时候,只有ViewStub会被初始化,当ViewStub被设置为可见或者调用viewStub.inflat()的时候,ViewStub所指向的布局才会被实例化,且ViewStub的布局属性都会传递给它所指向的布局。这样在运行时就可以判断要不要使用ViewStub来显示某个布局。
ViewStub的特点:
1.ViewStub只能inflate一次,之后ViewStub对象会被置空。
2.ViewStub只能用来inflate一个布局文件。
例子:
viewstub指向的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示viewStub" />
</LinearLayout>
Activity的布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载viewstub"/>
<ViewStub
android:id="@+id/no_data_viewstub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout="@layout/view_stub" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</LinearLayout>
调用:
public class MainActivity extends Activity {
private Button btn1;
private ViewStub noDataViewStub;
private boolean isShowing;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button) findViewById(R.id.button1);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isShowing) {
dismissEmptyView();
} else {
showEmptyView();
}
}
});
}
private void showEmptyView() {
if (noDataViewStub == null) {
noDataViewStub = (ViewStub)findViewById(R.id.no_data_viewstub);
noDataViewStub.inflate();
} else {
noDataViewStub.setVisibility(View.VISIBLE);
}
isShowing = true;
}
private void dismissEmptyView() {
if (noDataViewStub != null) {
noDataViewStub.setVisibility(View.GONE);
}
isShowing = false;
}
}
截图: