ViewStub
布局惰性加载机制,它是不可见的占据窗口大小为0的一个View,在运行时加载布局资源,当其visible或者调用inflate()方法时,就会变为可见,并将其本身加载出来的布局传递给父布局,但是他只能被加载一次,重复加载会报这个错误 Caused by: java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent。因为他加载完本身就不存在了,自然不能调用。
通常一个布局里面对应不同状态有好几个布局的时候,会写到一起,设置他们的Visibility属性为gone或者invisible,在代码中进行逻辑控制展现,比较麻烦,而且这样写虽然看不到,但扔被实例化,消耗资源,而ViewStub则进行了性能优化。
使用
首先我们在布局中定义一个ViewStub,里面有一个layout属性,就是我们要惰性加载的布局,在这里已经定义好了,只是默认不可见,不占据空间
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<ViewStub
android:id="@+id/stub"
android:layout="@layout/subtree"
android:layout_width="120dip"
android:layout_height="40dip" />
</LinearLayout>
接下来在主活动中进行处理
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewStub viewStub=findViewById(R.id.stub);
//viewStub.setVisibility(View.VISIBLE);
View inflated=viewStub.inflate();//与上一个写法一样效果(设置其可见与用inflate()加载一样)
//viewStub.inflate();写第二遍会报错,只能加载一次
TextView hintText=inflated.findViewById(R.id.text);
hintText.setText("qwerty");
}
}
直接调用 viewStub.inflate()也可以,只不过用View接一下,可以继续处理布局里面的控件。