1. 程式人生 > >Android UI優化之ViewStubs使用方法

Android UI優化之ViewStubs使用方法

1.含義解釋: ViewStub預設是不顯示的,也不佔用記憶體,載入時會被其他的佈局所替代才佔用記憶體並且才顯示出來,載入後如果只是隱藏用ViewStub.setVisiblitiy(View.GONE)就可以正常隱藏,但是不能釋放記憶體。 ViewStub和include的區別是:ViewStub中的佈局不會隨著它所在佈局的渲染而渲染,而<include>標籤中的佈局會隨著它所在佈局的渲染而渲染,ViewStub中的佈局只有在你需要的時候才會渲染到主介面中。 ViewStub只能在Activity中載入一次(除非重新建立Activity或者其他暫存器),載入後ViewStub就被ViewStub裡的layout佈局替換了最初的ViewStub,也就是載入後ViewStub就是相應的layout佈局,因此ViewStub只能載入一次,不能重複載入否則報錯。因此要做判斷,ViewStub.getParent()是否為空,如果不為空則載入,為空則不載入,詳情看下面程式碼。
2.java程式碼: 第一種寫法:判斷ViewStub是否為空 publicclassMyActivityextendsActivity{privatestaticfinalString TAG ="MyActivity";privateButton mBtn1, mBtn2;privateViewStub mVs;privateboolean isVisibility =false;@Overridepublicvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView
(R.layout.main);
mBtn1 =(Button) findViewById(R.id.btn1); mBtn2 =(Button) findViewById(R.id.btn2); mVs =(ViewStub) findViewById(R.id.vs); mBtn2.setOnClickListener(newView.OnClickListener(){@Overridepublicvoid onClick(View v){ //要判斷mVs是否為空,為空則說明已經載入過,不為空說明是第一次載入
if(mVs.getParent()!=null){Log.e(TAG,"vs is not null"); mVs.setInflatedId(R.id.inflate); mVs.setLayoutResource(R.layout.myinflate); mVs.inflate();}else{Log.e(TAG,"vs is null");if(!isVisibility){Log.e(TAG,"ViewStub is visible"); mVs.setVisibility(View.VISIBLE);}else{Log.e(TAG,"ViewStub is gone "); mVs.setVisibility(View.GONE);}} isVisibility =!isVisibility;}});}} 第二種寫法:直接作出判斷第二次就不再載入 publicclassMyActivityextendsActivity{privatestaticfinalString TAG ="MyActivity";privateButton mBtn1, mBtn2;privateViewStub mVs;privateboolean isStub =false;privateboolean isVisibility =false;@Overridepublicvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.main); mBtn1 =(Button) findViewById(R.id.btn1); mBtn2 =(Button) findViewById(R.id.btn2); mBtn2.setOnClickListener(newView.OnClickListener(){@Overridepublicvoid onClick(View v){if(!isStub){Log.e(TAG,"inflate ViewStub"); mVs =(ViewStub) findViewById(R.id.vs); mVs.setInflatedId(R.id.inflate); mVs.setLayoutResource(R.layout.myinflate); mVs.inflate();}else{if(!isVisibility){Log.e(TAG,"ViewStub is visible"); mVs.setVisibility(View.VISIBLE);}else{Log.e(TAG,"ViewStub is gone "); mVs.setVisibility(View.GONE);}} isVisibility =!isVisibility; isStub =true;}});}} 3.xml程式碼: main.layout程式碼: <?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><Buttonandroid:id="@+id/btn1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="100dp"android:text="Button_1"/><ViewStubandroid:id="@+id/vs"android:layout_width="match_parent"android:layout_height="wrap_content"android:inflatedId="@+id/inflate"android:layout="@layout/myinflate"/><Buttonandroid:id="@+id/btn2"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Button_2"/></LinearLayout> 解釋:我之前看別人講解一直不明白android:inflatedId="@+id/inflate"這個是什麼意思,後來看java程式碼才知道里面有個setInflate函式中的id就是這個id,這個id是隨便設定的,儘量和你的layout的id相近,為了佈局多時好辨認,layout的id是你要載入的佈局的id及下面的myinflate。 myinflate程式碼:這裡為了顯示清晰特意用LinearLayout嵌套了一個ImageView <?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:background="@drawable/ic_launcher"/></LinearLayout> 4.看看結構層次圖: (1)、未點選載入佈局是的結構圖:可以看到兩個按鈕中間沒有其他元件,結構為兩層,ViewStub和Button在一層上。
(2)、第一次載入後:可以看到兩個按鈕之間多出一個圖片元件,結構圖也變成了三層,與上圖相比LinearLayout是後即在出來的,而ViewStub元件也不見了,說明是被替換了。
(3)、隱藏mVs(即後加載進來的LinearLayout佈局)後的圖:層次和結構未變只是中間的圖片消失了。
5.結尾:ViewSub對於我們元件較多但又不需要一次性載入的應用優化是非常好的工具,希望大家熟練該元件的用法。 節約記憶體從優化開始。 轉載請註明出處。