趁今晚老大不在偷偷早下班,因此有時間繼續跟大夥扯扯UI設計之痛,也算一個是對上篇《Android:一個高效的UI纔是一個拉風的UI(一)》的完整補充吧。寫得很差的話你們儘管拍磚~(來!砸死我把~)html
前言android
前篇博客翻箱倒櫃的介紹了優化UI設計的兩個方法,第一個就是使用盡可能少的組件來實現佈局功能,第二個就是使用<merge>標籤來減小沒必要要的根節點,這兩個方法均可以提升應用UI的運行效率,可是夠了嗎?遠遠是不夠的,方法就像money同樣永遠不嫌多,因此再也不介紹多一些UI設計優化的方法說得過去麼?緩存
摸摸口袋裏面的都快四歲、運行着古老的android 2.2系統的屌絲機對於我來講,隨便一個大於10M的應用都有完爆他幾條街死機崩潰的超能力。可是對於某信來講,現在已經24M大小的它依然在屌絲機瀕臨垂死的硬件資源上運行如飛(至少沒崩潰過),讓我不得不感嘆應用優化作的至關不錯,也知足咱們這種屌絲在深深的寂寞夜晚來搖一發的情感需求。因此來講,一個應用能贏得市場,不只僅是贏得先機,而更多的是由於相同需求它功能作的比你好,相同功能它比你的簡約,相同簡約設計它運行比你快!app
----------------------------------我是分割線---------------------------------天王蓋地虎-------------------------------------------------------------less
排隊,一個一個慢慢來ide
當ActivityA跟ActivityB打招呼說:「偶要回家了,你來頂上」。說明就立刻溜得無影無蹤,這時候急呀,ActivityB趕忙measure呀、layout呀、draw呀趕忙搞出一個界面來應付觀衆先,忙的不亦樂乎;更要命這時候的是他們還要搞一個交接儀式——超炫超牛的切換動畫!然而在日益無窮大的慾望與逐漸乾癟的資源這強大的根本矛盾下,堅決果斷的當機了幾百毫秒。這一卡頓讓手機前的強迫症患者來講是多大的心理創傷,天然而然會說:「這軟件真渣!切個畫面都會總得頓一下才死心」。用戶體驗瞬間降爲0~模塊化
解決方案有哪些?固然很簡單的就是,取消牛逼哄哄的切換動畫咯,可是若是你的產品經理死活不一樣意那還不得另尋途徑。在不放棄動畫的前提下,咱們能夠把某些measure呀、layout呀、draw呀的步驟延遲在動畫後面執行不就行咯,排隊一個一個來,至於怎麼操做呢?那咱們要引入一個輕量級組件<ViewStub>,也就是動態加載的方法。工具
咱們一般使用它來作預加載處理,來改善頁面加載速度和提升流暢性,ViewStub自己不會佔用層級,它最終會被它指定的層級取代。有時候咱們也須要複雜的視圖且少用,咱們能夠按須要的時候裝載以便減小內存,提升體驗。之前咱們都是設置在佈局中,而後使用View.GONE屬性來隱藏組件,可是耗資源影響性能。總得來講這玩意就是一個輕量級的View,它一個看不見的,不佔佈局位置,佔用資源很是小的控件。佈局
下面上代碼:post
要加載的ActivityB佈局(複雜的動畫代碼請忽略)
<merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ViewStub android:id="@+id/mystub" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView android:id="@+id/loading_image" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/loading_image" /> </merge>
在這個UI界面中,當咱們切換ActivityB時,由於兼顧到動畫效果。因此咱們就讓ViewStub暫緩加載比較複雜的佈局,而先把較爲簡單的顯示加載畫面loading_image加載出來,當稍後時間咱們就在代碼裏面開始加載該佈局,見代碼以下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_loading); LoadHandler = new Handler(); myStub = (ViewStub)findViewById(R.id.mystub); loadingView = (ImageView)findViewById(R.id.loading_image); myStub.setLayoutResource(R.layout.layout_main);//設置加載資源 LoadHandler.postDelayed(new Runnable() { @Override public void run() { myStub.inflate();//開始加載複雜界面 loadingView.setVisibility(View.GONE);//隱藏臨時加載的簡單界面 } },500);
上面代碼實現了先執行復雜動畫,當切換界面到到500ms時,handler開始執行加載複雜的界面子線程,從而錯開了資源的集中利用,這裏使用的是動態添加ViewStub指向佈局資源的方法,簡單而實用吧,對於一個用戶來講,延遲半秒加載界面遠遠比切換畫面卡頓更容易接受。
使用ViewStub須要主要幾點:
一、ViewStub只能被Inflate一次,當Inflate以後ViewStub對象就被置爲空值,說得更通俗點就是當ViewStub被某個佈局Inflate後,就不能經過ViewStub來控制它,由於它已經功成身退了,天然對於須要不一樣場景下顯示隱藏的狀況建議用visibility。
二、ViewStub只能用來Inflate一個佈局文件,對於單個具體的View它是無能爲力的,固然若是把View搞在某個佈局文件中也是能夠接受的。
三、VIewStub中不能嵌套merge標籤。
重用佈局是一個好習慣
重用是一個好習慣,既然你們都常唸叨,無圖無真相呀樓主,爲了不你們說no picture you say a jb~這類回覆,我仍是勉勉強強上個圖吧。
這個界面由三個小部分組成,分別是標題欄、內容顯示和底端按鈕。若是你手指閒不住前先後後點一點,按一按;會發覺各個界面的風格驚人的類似!並且不只僅是在這軟件上會體現,並且市場上大部分應用都是這樣!其實說白了這就是一個風格的問題。
那麼,既然這麼多重複了,做爲二十一世紀標準碼農的咱們來講,咱們能忍受這種浪費嗎?因此咱們要用用<include>標籤——模塊化佈局。
佈局以下:多簡單的layout複用,你還會說你不喜歡用<include>標籤嗎?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <include android:id="@+id/head_menu" layout="@layout/head_menu" /> <include android:id="@+id/content" layout="@layout/content_showweibo" /> <include android:id="@+id/bottom_menu" layout="@layout/bottom_menu" /> </LinearLayout>
使用<include>的好處有:
一、模塊化佈局,提升重用率,易於往後的維護和擴展。
二、下降生成的app的體重,用戶的流量是很貴的!
簡單說說剩下的點
一、減小沒必要要的inflate
(1)對於inflate的佈局能夠直接緩存,用所有變量代替局部變量,避免下次需再次inflate
if (loadingView != null) { loadingView.setVisibility(View.VISIBLE); } else{ loadingView =LayoutInflater.from(context).inflate(R.layout.loadingView, this, true); }
(2)BaseAdapter中item的convertView緩存用法,詳細請參考《關於BaseAdapter的使用及優化心得》
PS:第一次寫的博文,寫的渣得不能看。。。。。。
二、避免有太多的視圖
每一個視圖都會消耗內存,在一個佈局中佈置太多的視圖,佈局會佔用過多的內存,假設一個佈局包含超過80個視圖,layoutopt可能會給出下面這樣的建議:
-1:-1 This layout has too many views: 83 views, it should have <= 80!
上面給出的建議是視圖數量不能超過80,固然最新的設備有可能可以支持這麼多視圖,但若是真的出現性能不佳的狀況,最好採納這個建議。
三、千萬別佈局嵌套太多
佈局不該該有太多的嵌套,layoutopt(和Android團隊)建議佈局保持在10級之內,即便是最大的平板電腦屏幕,佈局也不該該超過10級,RelativeLayout多是一個解決辦法,但它的用法更復雜,好在Eclipse中的Graphical Layout資源工具更新後,使得這一切變得更簡單。
下面是佈局嵌套太多時,layoutopt的輸出內容:
-1:-1 This layout has too many nested layouts: 12 levels, it should have <= 10! 305:318 This LinearLayout layout or its RelativeLayout parent is possibly useless
嵌套佈局警告一般伴隨有一些無用佈局的警告,有助於找出哪些佈局能夠移除,避免屏幕布局所有從新設計。
四、在某些場景下使用非主線程繪製的UI組件,具體組件名稱我忘了,後面想起來補上哈。
做者:enjoy風鈴
出處:http://www.cnblogs.com/net168/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然下次不給你轉載了。