Android布局優(yōu)化之ViewStub控件
ViewStub是Android布局優(yōu)化中一個很不錯的標(biāo)簽/控件,直接繼承自View。雖然Android開發(fā)人員基本上都聽說過,但是真正用的可能不多。
ViewStub可以理解成一個非常輕量級的View,與其他的控件一樣,有著自己的屬性及特定的方法。當(dāng)ViewStub使用在布局文件中時,當(dāng)程序inflate布局文件時,ViewStub本身也會被解析,且占據(jù)內(nèi)存控件,但是與其他控件相比,主要區(qū)別體現(xiàn)在以下幾點(diǎn):
1.當(dāng)布局文件inflate時,ViewStub控件雖然也占據(jù)內(nèi)存,但是相相比于其他控件,ViewStub所占內(nèi)存很?。?/p>
2.布局文件inflate時,ViewStub主要是作為一個“占位符”的性質(zhì),放置于view tree中,且ViewStub本身是不可見的。ViewStub中有一個layout屬性,指向ViewStub本身可能被替換掉的布局文件,在一定時機(jī)時,通過viewStub.inflate()完成此過程;
3.ViewStub本身是不可見的,對ViewStub setVisibility(..)與其他控件不一樣,ViewStub的setVisibility 成View.VISIBLE或INVISIBLE如果是首次使用,都會自動inflate其指向的布局文件,并替換ViewStub本身,再次使用則是相當(dāng)于對其指向的布局文件設(shè)置可見性。
這里需要注意的是:
1.ViewStub之所以常稱之為“延遲化加載”,是因?yàn)樵诮潭鄶?shù)情況下,程序無需顯示ViewStub所指向的布局文件,只有在特定的某些較少條件下,此時ViewStub所指向的布局文件才需要被inflate,且此布局文件直接將當(dāng)前ViewStub替換掉,具體是通過viewStub.infalte()或viewStub.setVisibility(View.VISIBLE)來完成;
2.正確把握住ViewStub的應(yīng)用場景非常重要,正如如1中所描述需求場景下,使用ViewStub可以優(yōu)化布局;
3.對ViewStub的inflate操作只能進(jìn)行一次,因?yàn)閕nflate的時候是將其指向的布局文件解析inflate并替換掉當(dāng)前ViewStub本身(由此體現(xiàn)出了ViewStub“占位符”性質(zhì)),一旦替換后,此時原來的布局文件中就沒有ViewStub控件了,因此,如果多次對ViewStub進(jìn)行infalte,會出現(xiàn)錯誤信息:ViewStub must have a non-null ViewGroup viewParent。
4.3中所講到的ViewStub指向的布局文件解析inflate并替換掉當(dāng)前ViewStub本身,并不是完全意義上的替換(與include標(biāo)簽還不太一樣),替換時,布局文件的layout params是以ViewStub為準(zhǔn),其他布局屬性是以布局文件自身為準(zhǔn)。
下面看一下簡單的需求場景:在listview顯示列表數(shù)據(jù)時,可能會出現(xiàn)服務(wù)端一條數(shù)據(jù)都沒有的情況,此時顯示一個EmptyView,提示用戶暫無數(shù)據(jù)。此時考慮到實(shí)際應(yīng)用中EmptyView顯示出來的機(jī)會相當(dāng)小,因此,可以在布局文件中使用ViewStub站位,然后確實(shí)沒有數(shù)據(jù)時才viewStub.infalte()。
相關(guān)部分代碼如下:
public void showEmptyView() { listview.setVisibility(View.GONE); if (noDataView == null) { ViewStub noDataViewStub = (ViewStub) view.findViewById(R.id.no_data_viewstub); noDataView = noDataViewStub.inflate(); } else { noDataView.setVisibility(View.VISIBLE); } } public void showListView(){ listview.setVisibility(View.VISIBLE); if(noDataView != null){ noDataView.setVisibility(View.GONE); } }
特別需要注意的是對ViewStub是否已經(jīng)inflate的判斷。
在Listview Item中,有時候可能遇到如下場景:在不同的列表頁item的布局一部分不同,但相對于整個item布局來說又不是很多,此時最常見的有如下兩種處理:
1.對不同的部分都寫出來,放到一個item文件中,然后邏輯分別處理不同部分的顯示與否(View.VISIBLE和View.GONE);
2.對這兩種不同的item整個部分都分別區(qū)分開,完全寫成兩個item文件,然后結(jié)合listView顯示不同布局分別做邏輯處理(通過getItemType()等方式)。
以上兩種處理方式其實(shí)都可以,第一種方式邏輯清晰,非常靈活,只是在一定程度上增加了內(nèi)存和資源消耗。第二種方式是的布局文件有重復(fù)(雖然相同部分可以通過include,但是邏輯上還是有重復(fù)的),包括邏輯上處理的代碼實(shí)質(zhì)上的重復(fù)。一般對于有較大不同的item布局推薦采用此種方式。
有時候結(jié)合需求,可以在第一種方式的基礎(chǔ)上,結(jié)合ViewStub“占位符”可以比較好的完成此類需求。也相當(dāng)于是兩種方式的一種折中形式,但同時兼顧了內(nèi)存和資源消耗以及不同的布局邏輯控件。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)之ImageSwitcher相冊功能實(shí)例分析
這篇文章主要介紹了Android開發(fā)之ImageSwitcher相冊功能,結(jié)合實(shí)例形式分析了Android ImageSwitcher相冊的原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-03-03android 開發(fā)教程之日歷項(xiàng)目實(shí)踐(一)
決定開始學(xué)習(xí) Android 平臺下的軟件開發(fā),以日歷作為實(shí)踐項(xiàng)目,進(jìn)行一周后,基本完成,有需要的朋友可以參考下2013-01-01android activity設(shè)置無標(biāo)題實(shí)現(xiàn)全屏
本文將詳細(xì)介紹Android如何設(shè)置Activity全屏和無標(biāo)題的實(shí)現(xiàn)方法,需要的朋友可以參考下2012-12-12Android編程實(shí)現(xiàn)顯示在標(biāo)題上的進(jìn)度條功能【附源碼下載】
這篇文章主要介紹了Android編程實(shí)現(xiàn)顯示在標(biāo)題上的進(jìn)度條功能,涉及Android界面布局及相關(guān)組件屬性設(shè)置技巧,并附帶完整實(shí)例源碼供讀者下載參考,需要的朋友可以參考下2018-01-01Adnroid 自定義ProgressDialog加載中(加載圈)
這篇文章主要介紹了Adnroid 自定義ProgressDialog加載中(加載圈),需要的朋友可以參考下2017-06-06Android使用ViewPager完成app引導(dǎo)頁
這篇文章主要為大家詳細(xì)介紹了Android使用ViewPager完成app引導(dǎo)頁,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-11-11