Android一些你需要知道的布局優化技巧

2021-03-02 鴻洋

本文由唯鹿投稿。

唯鹿的博客地址:

http://blog.csdn.net/qq_17766199

今天分享一些layout布局書寫中的一些技巧,希望看過之後你也一樣可以寫出性價比高的布局。我個人的目標是用最少的View寫出一樣效果的布局。因為我相信View的數量減少伴隨著的就是層級的減少。從而達到結構清晰,渲染速度快的效果。順著這個邏輯,我將優化分為重用、合併、按需載入。

< include>標籤可以在一個布局中引入另外一個布局,這個的好處顯而易見。類似於我們經常用到的工具類,隨用隨調。便於統一修改使用。

舉例說明:首先寫一個公共的布局title_bar.xml,app中常用的標題欄。


預覽:

下來activity_main.xml調用它:


運行後效果和預覽一樣一樣的。當然我們也可以在< include>標籤當中重新設置寬高等layout屬性。

減少嵌套

首先我們心中要有一個大原則:儘量保持布局層級的扁平化。在這個大原則下我們要知道:

在不影響層級深度的情況下,使用LinearLayout而不是RelativeLayout。因為RelativeLayout會讓子View調用2次onMeasure,LinearLayout 在有weight時,才會讓子View調用2次onMeasure。Measure的耗時越長那麼繪製效率就低。

如果非要是嵌套,那麼儘量避免RelativeLayout嵌套RelativeLayout。這簡直就是惡性循環,喪心病狂。

實現方法就不細說了,大家都是明白人。

< merge/>

< merge/>主要用來去除不必要的FrameLayout。它的使用最理想的情況就是你的根布局是FrameLayout,同時沒有使用background等屬性。這時可以直接替換。因為我們布局外層就是FrameLayout,直接「合併」。

舉例說明:比如上面用到的activity_main.xml文件,我們通過View Hierarchy工具看一下,如圖:

可以看到,最外層是FrameLayout,下來我們修改一下。


再次查看:

很明顯少了一層RelativeLayout,當然運行效果是一樣的。當然如果我們不需要title_bar.xml中的綠色背景,那麼可以這樣修改。


運行效果:

運行查看層級,如下圖:

結果很明顯。

這個我就不細說了,舉一個我們項目中的一個例子,代碼一看便知。

首先要完成的效果是如下圖:

這種效果很常見,一般實現方法是這樣。(貌似沒人這樣寫吧,哈哈)


效果圖:

那麼我們優化一下:


你沒有看錯,少了兩個ImageView和去除嵌套LinearLayout。效果不用說一樣一樣的。當然EditView等也一樣的,還有屬性drawableBottom和drawableTop供你使用。同時利用代碼setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)可以讓我們動態去設置圖片。

先上我們需要實現的效果圖:

效果很簡單,實現代碼


這裡我偷懶了多嵌套了一層LinearLayout,但。。。這不重要,我先直接修改。

優化後代碼:


老規矩,效果一樣一樣的。可以看到我們僅僅利

用Android:lineSpacingExtra="8dp"這一行代碼就省去了3個TextView,如果行數更多呢?是不是方便多了。

其中:lineSpacingExtra屬性代表的是行間距,他默認是0,是一個絕對高度值。同時還有lineSpacingMultiplier屬性,它代表行間距倍數,默認為1.0f,是一個相對高度值。

我們來使用一下:


當然了這兩條屬性可以同時使用,查看源碼可以知道,他們的高度計算規則為mTextPaint.getFontMetricsInt(null) * 行間距倍數 + 行間距。

使用Spannable或Html.fromHtml   

這裡也是舉例說明,比如下圖效果:

如果實現上圖紅框中的效果,笨辦法就是寫三個TextView,「¥」,「價格」,「門市價」分別實現,其實用一個TextVIew就可以實現,類似如下代碼:


同樣Html.fromHtml也可以實現。這樣不就減少了兩個TextView了。


在開發中經常會遇到這樣的情況,會在程序運行時動態根據條件來決定顯示哪個View或某個布局。那麼通常做法就是把用到的View都寫在布局中,然後在代碼中動態的更改它的可見性。但是它的這樣仍然會創建View,會影響性能。

這時就可以用到ViewStub了,ViewStub是一個輕量級的View,不佔布局位置,佔用資源非常小。

例子:比如我們請求網絡加載列表,如果網絡異常或者加載失敗我們可以顯示一個提示View,上面可以點擊重新加載。當然一直沒有錯誤時,我們就不顯示。


hint_view.xml就是這個提示View,可以根據情況自己寫。

用法


用法很簡單,記得一旦ViewStub可見或是被inflate了,ViewStub就不存在了,取而代之的是被inflate的Layout。所以它也被稱做惰性控制項。

還記得上文用TextView同時顯示圖片和文字中的例子嗎?我們可以看到每個條目之間都是有一根分隔線的,那麼怎麼實現呢?別人我不知道,反正我原來是用一個View設置高度實現的。相信一定有人和我一樣。

那麼老辦法我就不演示了,直接上代碼:


效果圖:

實現的核心部分其實是LinearLayout的這兩行。

android:divider="@drawable/divider"android:showDividers="middle"

其中divider.xml是分隔線樣式。


showDividers 是分隔線的顯示位置,beginning、middle、end分別代表顯示在開始位置,中間,末尾。

還有dividerPadding屬性這裡沒有用到,意思很明確給divider添加padding。感興趣可以試試。

還是接著上面的例子,如果要給條目中間添加間距,怎麼實現呢?當然也很簡單,比如添加一個高10dp的View,或者使用android:layout_marginTop="10dp"等方法。但是增加View違背了我們的初衷,並且影響性能。使用過多的margin其實會影響代碼的可讀性。

這時你就可以使用Space,他是一個輕量級的。

實現代碼與效果:



防止過度繪製參考
總結

最後想想如果沒有用這些技巧,我們要寫多少代碼,多少View?效果是不是槓槓的!其實上面說了這麼多,具體的情景使用還是要看項目的具體情況,在性能面前有些還是要取捨的,但千萬不能為了優化而優化。優化也是不斷積累的過程,不要指望立竿見影。願大家都能寫出一手漂亮的布局。

如果你有好的文章想和大家分享,歡迎投稿,直接向我投遞文章連結即可。

歡迎長按下圖->識別圖中二維碼或者掃一掃關注我的公眾號:

相關焦點

  • 最全的Android內存優化技巧
    本文主要介紹性能優化的一些手段,但是為了便於理解以及融會貫通,建議先了解Android內存管理機制,本文將從四個角度來介紹內存優化技巧減小對象的內存佔用儘量減少新分配出來的對象佔用內存的大小,使用更加輕量的對象1.
  • android 復用 布局優化專題及常見問題 - CSDN
    在布局優化中,Androi的官方提到了這三種布局<include />、<merge />、<ViewStub />,並介紹了這三種布局各有的優勢,下面也是簡單說一下怎麼使用.
  • Android基礎 - 如何做魯棒性更高的布局
    你就會發現他們在父布局中被等分寬高了,利用這個特性原理來構建布局則可以輕鬆做到健壯性更高不具效果而不需要擔心很多界面重疊、錯位的問題:所謂魯棒性,可以理解成可靠性,也於容錯性相關,那麼你在下邊的線性布局方案中可有見過一句android:layout_toLeftOf、android:layout_toStartOf之類的需要綁定其他組件的語句麼?
  • android水平布局和垂直布局 - CSDN
    一、線性布局(LinearLayout)線性布局:線性布局是我們在開發中最常見的布局方式之一,線性布局可以分為水平線性布局和垂直線性布局這兩種布局方式線性布局的屬性(決定布局中元素的位置和布局):android:layout_gravity ( 是本元素相對於父元素的對齊方式 )android:gravity
  • android絕對布局
    絕對布局由AbsoluteLayout代表。絕對布局就像java AWT編程中的空布局,就是Android不提供任何布局控制而是由開發人員自己通過X坐標、Y坐標來控制組件的位置。當使用AbsoluteLayout作為布局容器時,布局容器不再管理子組件的位置、大小---這些都需要開發人員自己控制。
  • 帶你了解 Android 約束布局 ConstraintLayout
    ConstraintLayout是Android新推出的一個布局,其性能更好,連官方的hello world都用ConstraintLayout來寫了。所以極力推薦使用ConstraintLayout來編寫布局。本文主要介紹一下如何使用代碼來編寫ConstraintLayout布局。好了,開始我們的徵程。
  • android 布局 覆蓋 - CSDN
    項目中listview中嵌套checkbox,將父控制項設置為android:descendantFocusability="blocksDescendants",這樣設置為的是:會覆蓋子類控制項而直接獲得焦點,即點擊listview的item區域即可選中checkbox。
  • android布局詳解專題及常見問題 - CSDN
    若原根節點已經設置了android:id屬性值,那麼<include>標籤的android:id屬性值將被覆蓋workspace_screen.xml布局文件中的根節點的android:id屬性值。<include>標籤還可以覆蓋被引用的布局文件根節點額所有與布局有關的屬性(也就是以「android:layout_」開頭的屬性)。
  • Android ConstraintLayout約束布局可視化工具使用~
    ,今天我們簡單看看這個布局的使用。簡單介紹一下這個布局:頂部那一小條是一些快捷操作的操作欄>左上角是顯示的官方控制項,可以直接拖動到視圖上,就可以添加控制項了左下角是顯示當前布局的層級嵌套,點擊每個控制項也可以選中,然後進行一系列操作右邊是一些屬性的調整,上半部分可以調整偏移,layout_margin 以及 layout_width,layout_height
  • Android性能優化典範
    13)Optimizing Your Layout下圖舉例演示了如何優化ListItem的布局,通過RelativeLayout替代舊方案中的嵌套LinearLayout來優化布局代碼的不同寫法會影響到Java編譯器的優化效率。例如for循環的不同寫法就會對編譯器優化這段代碼產生不同的效率,當程序中包含大量這種可優化的代碼的時候,運算性能就會出現問題。想要知道如何優化代碼的運算性能就需要知道代碼在硬體層的執行差異。
  • 幾乎是史上最全最實用的Android性能全面分析與優化方案研究
    藉助性能優化工具分析解決問題性能優化指標性能問題分類1、渲染問題: 過度繪製、布局冗雜2、內存問題: 內存浪費(內存管理)、內存洩漏3、功耗問題: 耗電性能優化原則和方法2、內存內存大小:峰值越低越好,需要優化前後做對比內存洩漏:需要用工具檢查對比優化前後3、功耗一、渲染問題先來看看造成應用UI卡頓的常見原因都有哪些?
  • android 動態創建布局文件 - CSDN
    在應用程式開發時有時不同的狀態需要對應不同的布局文件。其實比較簡單,以橫屏與豎屏變換為例切換不同的布局文件。首先,創建一個項目,在Manifest文件中為MainActivity添加configChanges屬性如下:<span style="white-space:pre"> </span><activity android:name=".MyActivity" android:label="@string/app_name"
  • Android性能優化:手把手帶你全面實現內存優化
    最近有想換工作的同學們,可參考《5月技術崗位內推|RN開發招聘啦》,再往下看,一篇關於性能優化的好文章,很值得去學習。前言在 Android開發中,性能優化策略十分重要本文主要講解性能優化中的內存優化,希望你們會喜歡目錄
  • Android性能優化:帶你全面實現內存優化
    4.5 常見使用優化原因一些常見使用也可能引發大量的內存問題,下面我將詳細介紹。優化方案還有1個內存優化的終極方案:調大 虛擬機Dalvik的堆內存大小即 在AndroidManifest.xml的application標籤中增加一個android:largeHeap屬性(值 = true
  • 是時候讓 Android Tools 屬性拯救你了
    當然你肯定也會遇到這些「髒數據」給你帶來的困擾:測試的時候某些地方出現了本不該出現的數據,事後可能一拍腦門才發現,原來是布局中控制項預覽數據沒有清除導致的。如果是 RecyclerView,在後臺接口尚能測試的情況下,你是否又要自己生成「假數據」並手寫 Adapter 呢?
  • android 中常用的五種布局 - CSDN
    相對布局特有的屬性:值是某個控制項和布局的idandroid:layout_below 在某控制項的下方android:layout_above 在某控制項的的上方android:layout_toLeftOf 在某控制項的左邊android:layout_toRightOf 在某控制項的右邊android:layout_alignTop 本控制項的上邊緣和某控制項的的上邊緣對齊
  • Android應用耗電量分析與優化建議
    分析和記錄之類的操作不需要實時進行。傳感器方面設備屏幕亮度、顏色背景等需要考慮,但除了閱讀類等應用,一般是不太考慮屏幕消耗的。更多的是對GPS的使用注意,減少無用的GPS請求和及時關閉GPS搜索。優化建議開發過程中可以嘗試通過調整任務優先級等策略來達到降低損耗的目的,使用JobScheduler是個不錯的選擇:可以推遲的非面向用戶的任務(如定期資料庫數據更新);當充電時才希望執行的工作(如備份數據);需要訪問網絡或 Wi-Fi 連接的任務(如向伺服器拉取配置數據);零散任務合併到一個批次去定期運行
  • Android開發必備的「80」個開源庫
    >整理一些比較好的 Android 開發教程http://bxbxbai.github.io/2014/10/07/android-develop-resource/Segmentfault 上回答較好的一些問題https://segmentfault.com/a/1190000004063006Android 界面設計視覺規範
  • android通過代碼實現的多布局專題及常見問題 - CSDN
    Seekbar常規使用方式通過xml布局方式實現,但是由於我們的是sdk,不能有xml布局,所以SeekBar使用純代碼實現。但是這樣就遇到了很多問題。 首先是SeekBar設置setProgressDrawable問題。
  • Android 開發應該掌握的 Proguard 技巧
    Entry Points非常重要,Proguard的壓縮,優化,混淆功能是以Entry Point作為依據的(預檢不需要以此為依據)。Proguard配置文件的依據說起重命名,為什麼需要保留一些類和類的成員(方法和變量)不被重命名呢 ?