編輯:關於Android編程
android對布局優化提供了三種布局:
這三種布局都可以簡化我們的布局文件,優化繪制流程,下面我們簡單看一下這三種組件的使用方式。
1、重用布局
"http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=”match_parent” android:layout_height=”match_parent” android:background="@color/app_bg" android:gravity="center_horizontal"> "@layout/titlebar"/> "wrap_content" android:text="@string/hello" android:padding="10dp" /> ...
1)標簽可以使用單獨的layout屬性,這個也是必須使用的。
2)可以使用其他屬性。標簽若指定了ID屬性,而你的layout也定義了ID,則你的layout的ID會被覆蓋。
3)在include標簽中所有的android:layout_*都是有效的,前提是必須要寫layout_width和layout_height兩個屬性。
2、減少視圖層級
這個標簽在UI的結構優化中起著非常重要的作用,它可以刪減多余的層級,優化UI。多用於替換FrameLayout或者當一個布局包含另一個時,標簽消除視圖層次結構中多余的視圖組。例如你的主布局文件是垂直布局,引入了一個垂直布局的include,這是如果include布局使用的LinearLayout就沒意義了,使用的話反而減慢你的UI表現。這時可以使用標簽優化。
merge>
現在,當你添加該布局文件時(使用標簽),系統忽略節點並且直接添加兩個Button。
3、需要時使用
這個標簽最大的優點是當你需要時才會加載,使用他並不會影響UI初始化時的性能。各種不常用的布局想進度條、顯示錯誤消息等可以使用這個標簽,以減少內存使用量,加快渲染速度。
當你想加載布局時,可以使用下面其中一種方法:
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE); // or View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
android中的過度繪制
android開發者選項中有一項是:“調試GPU過度繪制”,過度繪制描述的是屏幕上一個像素在單個幀中被重繪了多少次。比如一個有背景的TextView,那麼顯示文本的那些像素至少繪制了兩次,一次是背景,一次是文本。過度繪制是Android平台上一個很棘手的性能問題,它非常容易出現。
過度繪制產生的原因
太多重疊的背景
重疊著的背景有時候是有必要的,有時候是沒必要的。這要視你的項目具體情況而定.
太多疊加的View
或者本來這個UI布局就很復雜或者你是為了追求一個炫麗的視覺效果,這都有可能使得很多view疊加在一起。這個情況非常普遍,下面的建議中會談談怎麼減少這種情況帶來的影響。
復雜的Layout層級
復雜的層級關系,這個在布局中也很常見,下面也會說這種情況怎麼做可以盡可能的減少過度繪制。
建議
太多重疊的背景
這個問題其實最容易解決,建議就是檢查你在布局和代碼中設置的背景,有些背景是被隱藏在底下的,它永遠不可能顯示出來,這種沒必要的背景一定要移除,因為它很可能會嚴重影響到app的性能。如果采用的是selector的背景,將normal狀態的color設置為”@android:color/transparent”,也同樣可以解決問題。
太多重疊的view
第一個建議是:使用ViewStub來加載一些不常用的布局,它是一個輕量級且默認不可見的視圖,可以動態的加載一個布局,只有你用到這個重疊著的view的時候才加載,推遲加載的時間。第二個建議是:如果使用了類似viewpager+Fragment這樣的組合或者有多個Fragment在一個界面上,需要控制Fragment的顯示和隱藏,盡量使用動態地Inflation view,它的性能要比SetVisiblity好。
復雜的Layout層級
這裡的建議比較多一些,首先推薦用Android提供的布局工具Hierarchy Viewer來檢查和優化布局。第一個建議是:如果嵌套的線性布局加深了布局層次,可以使用相對布局來取代。第二個建議是:用標簽來合並布局,這可以減少布局層次。第三個建議是:用標簽來重用布局,抽取通用的布局可以讓布局的邏輯更清晰明了。記住,這些建議的最終目的都是使得你的Layout在Hierarchy Viewer裡變得寬而淺,而不是窄而深。
實例分析
(一)啟用調試GPU過度繪制功能;
設置-》其他高級設置-》開發者選項-》調試GPU過度繪制;
我們可以看到我們的手機界面中顯現除了一下背景顏色,這裡介紹一下這些背景顏色表示的就是布局過度繪制的情況,其中:
藍色:一次繪制
綠色:兩次繪制
淡紅:三次繪制
深紅:四次繪制
所以當我們App的界面中深紅或者是淡紅的部分較多時我們可以分析一下我們的界面布局是否存在過度繪制的情況。
(二)打開我們的測試頁面,這裡以一個意見反饋為例:
這裡可以看出整個頁面你的布局為藍色,即渲染了一次;
輸入框中的北京為綠色,渲染了兩次;
文字部分為淡紅色,渲染了三次;
整體來看整個布局渲染基本正常,不存在過度繪制的問題;
下面這是布局文件的xml定義:
"http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/c10"> "match_parent" android:layout_width="match_parent"> "@+id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="126dp" android:layout_marginTop="18dp" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:paddingTop="@dimen/s2" android:paddingBottom="@dimen/s2" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="盡量詳細描述您遇到的問題,感謝您給我們提出建議" android:gravity="top|left" /> "@+id/feedback_contact_edit" android:layout_below="@id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="45dp" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="請輸入您的手機號碼、QQ或者郵箱" android:singleLine="true" /> "@+id/feedback_info_text" android:layout_below="@id/feedback_contact_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#00000000" android:textSize="@dimen/f5" android:textColor="@color/c5" android:text="留下聯系方式,以便能更好更快的給您答復,還可能有意外獎勵哦" /> "@layout/b3_button" android:layout_width="match_parent" android:layout_height="48dp" android:layout_below="@id/feedback_info_text" android:layout_marginLeft="@dimen/s4" android:layout_marginRight="@dimen/s4" android:layout_marginTop="12dp" android:gravity="center" android:text="提交" android:textSize="@dimen/f2" android:textColor="@color/c11" /> RelativeLayout>
下面我們為整個布局文件多添加一層布局控件
"http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/c10"> "match_parent" android:layout_height="match_parent"> "match_parent" android:layout_width="match_parent"> "@+id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="126dp" android:layout_marginTop="18dp" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:paddingTop="@dimen/s2" android:paddingBottom="@dimen/s2" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="盡量詳細描述您遇到的問題,感謝您給我們提出建議" android:gravity="top|left" /> "@+id/feedback_contact_edit" android:layout_below="@id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="45dp" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="請輸入您的手機號碼、QQ或者郵箱" android:singleLine="true" /> "@+id/feedback_info_text" android:layout_below="@id/feedback_contact_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#00000000" android:textSize="@dimen/f5" android:textColor="@color/c5" android:text="留下聯系方式,以便能更好更快的給您答復,還可能有意外獎勵哦" /> "@layout/b3_button" android:layout_width="match_parent" android:layout_height="48dp" android:layout_below="@id/feedback_info_text" android:layout_marginLeft="@dimen/s4" android:layout_marginRight="@dimen/s4" android:layout_marginTop="12dp" android:gravity="center" android:text="提交" android:textSize="@dimen/f2" android:textColor="@color/c11" /> RelativeLayout>
再次執行查看繪制情況:
咦?沒什麼變化麼?這是怎麼回事?其實對於android系統來說,在布局文件中新添加一個布局控件只是會讓它存在布局的邏輯關系而不會為這個布局控件重新繪制一次,只有這個布局控件設置background的時候才會重新繪制一次,下面我們為這個RelativeLayout設置以下background
"http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/c10"> "match_parent" android:layout_height="match_parent" android:background="@color/c10" > "match_parent" android:layout_width="match_parent"> "@+id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="126dp" android:layout_marginTop="18dp" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:paddingTop="@dimen/s2" android:paddingBottom="@dimen/s2" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="盡量詳細描述您遇到的問題,感謝您給我們提出建議" android:gravity="top|left" /> "@+id/feedback_contact_edit" android:layout_below="@id/feedback_content_edit" android:layout_width="match_parent" android:layout_height="45dp" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#FFFFFF" android:textColorHint="@color/c4" android:textSize="@dimen/f4" android:textColor="@color/c3" android:hint="請輸入您的手機號碼、QQ或者郵箱" android:singleLine="true" /> "@+id/feedback_info_text" android:layout_below="@id/feedback_contact_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/s3" android:paddingLeft="@dimen/s3" android:paddingRight="@dimen/s3" android:background="#00000000" android:textSize="@dimen/f5" android:textColor="@color/c5" android:text="留下聯系方式,以便能更好更快的給您答復,還可能有意外獎勵哦" /> "@layout/b3_button" android:layout_width="match_parent" android:layout_height="48dp" android:layout_below="@id/feedback_info_text" android:layout_marginLeft="@dimen/s4" android:layout_marginRight="@dimen/s4" android:layout_marginTop="12dp" android:gravity="center" android:text="提交" android:textSize="@dimen/f2" android:textColor="@color/c11" /> RelativeLayout>
查看界面的繪制情況,我們發現:
怎麼樣?藍色的區域變成綠色了,綠色的區域變成淡紅色了,淡紅色的區域變成紅色了,說明界面中存在過度繪制的情況,這時候我們就該考慮一下是否存在優化的可能了。
其他UI優化的Tips
使用LieanrLayout替代RelativeLayout布局;
布局文件中減少布局層級,減少組件的嵌套層數;
當有多個組件有相似的屬性時,可以使用styles,復用樣式定義;
通過定義drawable來替代圖片資源的使用,降低內存消耗;
總結:
過度繪制描述的是屏幕上一個像素在單個幀中被重繪了多少次。
藍色:繪制一次
綠色:繪制兩次
淡紅色:繪制三次
紅色:繪制四次
為布局文件添加布局控件不會導致界面繪制次數的增加,只有為布局空間設置background時才會導致繪制次數的增加
當我們的界面紅色區域較多時就需要考慮我們是否存在過度繪制的問題了
可以使用merge、include、ViewStub簡化布局文件優化布局繪制流程
在使用布局文件的時候盡量減少布局層級
導入Android工程出現unable to get system library for the project 錯誤提示問題與現象:當向eclipse導
如今android N都已經出來了,作為一個android開發者如果還不知道如何使用android5.X的 RecyclerView未免有點說不過去了。RecyclerV
效果圖: .java文件有MainActivity.java、FileService.java、FileServiceTest.java, .xml文
BottomBar BottomBar是Github上的一個開源框架,因為從1.3.3開始不支持fragments了,要自己配置,弄了很久,不管是app的fragmen