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接一下,可以繼續處理佈局裏面的控件。