歡迎光臨
每天分享高質量文章

Android基礎 – 如何做魯棒性更高的佈局

作者:kongzue
鏈接:https://www.jianshu.com/p/174bcb6c0d93

前情提要

這是一篇寫給入坑 Android 開發新手的文章,它可能不太適合老手閱讀,也可能帶有一些我個人的理解和見地,但我是衷心希望更多的新人開發者能從這篇文章中獲取知識,讓我們一同進步。當然了,其中可能不可避免的會存在一些遺漏和錯誤,也希望大家多多指正。

目錄

1、什麼是佈局&盒子模型
2、盡可能使用LinearLayout構建佈局
3、顱內秒建模,指哪打哪
4、還有被遺忘的圖片兄弟咋辦呀?

什麼是佈局&盒子模型

移動智慧設備是目前最火的人機交互設備之一,應市場的召喚,作為開發者的我們想要在這樣的設備中開發出優質的作品那麼就需要讓我們的產品具備更好的視覺和功能體驗,而佈局,正是構建視覺體驗的基礎。良好的佈局構建可以幫助我們更快、更好的完成一個應用視覺開發,那麼將UI產出的圖形稿件變現成為可以操作的APP界面,我們就應該能夠完成魯棒性更高的佈局開發。

佈局開發是APP前端開發中最重要的一環,而目前我們所做的大部分APP開發離不開一種模型,即盒子模型,字面意思理解,就是一個盒子套一個盒子,外邊的盒子位置的變動裡邊的小盒子也會跟著變,反映到佈局上,即父佈局和子佈局,但是註意了,在Android提供的基礎組件中,有些組件可以構成所謂的“盒子”,而有些組件則不行,他們只能作為放在盒子內部拿來使用的存在。典型的“盒子”即繼承自父類“ViewGroup”的相對佈局 RelativeLayout 以及線性佈局 LinearLayout,當然了還有滾動佈局 ScrollView、網格佈局 GridLayout 等十分的多,而我們日常使用到的按鈕 Button、圖像ImageView、文本TextView則不是“盒子”了,他們只能作為子佈局放在盒子內,以上,就是盒子模型的簡單陳述了。

盡可能使用LinearLayout構建佈局

相對佈局RelativeLayout可能是新手入坑Android開發後最常用的佈局,因為其跟我們日常所理解的畫布類似,我們想將哪個部件放在畫布的哪個位置都是非常自由的,但事實上,從結構的完整性上講,RelativeLayout並不是真正適合作為佈局主體進行佈局構建方式,雖然看似其十分好用,但實際上當我們將作為底子的畫布變換一個方向和大小,可能就沒那麼方便了:

使用RelativeLayout構建的佈局.png

這可能會直接導致界面混亂,以至於出現“換了個手機就不能用了”的尷尬情況,那麼如何避免此類問題呢?事實上,可能讓我們覺得並不好用的LinearLayout就可以幫我們更好的解決這個問題。

使用LinearLayout構建的佈局沒有問題.png

使用LinearLayout佈局可以更加方便的完成如上圖所示的佈局,但在此之前,我們需要明白一個在LinearLayout佈局中的子佈局特有的屬性:layout_weight,當一個子佈局放在LinearLayout中的時候,layout_weight屬性即可使用,它的意義在於“權重”,在線性佈局中,子佈局都是按照從上到下、從左到右來排列的,但當子佈局的寬度或高度為match_parent,即占滿父佈局的全部寬高度時,這裡就會存在一個問題,其他的子佈局會被擠出屏幕外,此時要讓他們“平均”顯示,就需要一個引數layout_weight了,將所有子佈局設置layout_weight=”1″,你就會發現他們在父佈局中被等分寬高了,利用這個特性原理來構建佈局則可以輕鬆做到健壯性更高不具效果而不需要擔心很多界面重疊、錯位的問題:

相對佈局和線性佈局.png

我個人相對更推薦線性佈局為主進行主體佈局的開發,這樣可以規避掉很多問題,提升佈局的魯棒性。具體表現在哪裡呢?看下邊這個截圖:

要實現的效果.png

我們要實現上邊的這個效果,用相對佈局的代碼如下:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">


        <Button
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:text="1" />


        <Button
            android:id="@+id/button2"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:text="2" />


        <Button
            android:id="@+id/button3"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_below="@+id/button2"
            android:layout_toLeftOf="@+id/button2"
            android:layout_toStartOf="@+id/button2"
            android:text="3" />


    RelativeLayout>

用線性佈局寫的代碼如下:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <Button
                android:id="@+id/button1"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="1" />


            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_weight="1" />


            <Button
                android:id="@+id/button2"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="2" />


        LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_weight="1" />


            <Button
                android:id="@+id/button3"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="3" />


            <View
                android:layout_width="70dp"
                android:layout_height="70dp" />


        LinearLayout>

    LinearLayout>

看似線性佈局的代碼多了是不是?那麼它的優勢到底在哪裡呢?所謂魯棒性,可以理解成可靠性,也於容錯性相關,那麼你在下邊的線性佈局方案中可有見過一句android:layout_toLeftOf、android:layout_toStartOf之類的需要系結其他組件的陳述句麽?這裡最關鍵的意義在於,採用線性佈局構建的代碼方案中,不存在某個子佈局組件和其他子佈局組件存在關聯關係的情況,那麼這在後期維護專案的過程中,如果出現需要刪除、隱藏掉其可能存在關聯關係的佈局的情況時,我們的界面不會出現任何錯誤的情況,其魯棒性遠高於採用相對佈局的代碼。

如果經歷過大型專案我們都會知道,在大型專案中可能存在大量的佈局、組件,這樣的情況下如果需要對其中某一部分進行修改,那麼極可能出現牽一發而動全身的問題,很多問題還不會立刻表現出來,而是會在某些條件達成時出現問題,帶來不良的用戶體驗,因此,在日常佈局設計時,除了可能存在需要居中某些子佈局組件而使用相對佈局的情況外,我建議能使用線性佈局就是用線性佈局來進行構建。

顱內秒建模,指哪打哪

相對一些特殊的應用,我們日常能遇到需要開發的大多是一些業務系統,而這,更是線性佈局的主場了。

一日讀.png

「一日讀」是我開源在Github上的輕圖片、視頻以及知乎日報功能的客戶端( https://github.com/kongzue/EnjoyLife ),這裡就拿它的關於界面來舉例好了,在這個界面中,主體採用了一個頂屏幕寬高的縱向LinearLayout,裡邊的圖片、文字都是採用margin的形式進行分隔,而頂部的導航條,則需要懸浮在主界面之上,那麼它則採用了一個橫向的線性佈局作為主體設計了傳回按鈕、分享按鈕以及標題,但其中的標題需要居中,則在其上疊加了一層相對佈局來完成。

此佈局在橫向、各種解析度(非極端)的情況下均不會出現任何問題,且因為不存在大量的相對代碼,維護成本更低。

彩蛋·還有被遺忘的圖片兄弟咋辦呀?

線性佈局相對於相對佈局確實更具優勢,但在我們開發過程中也會遇到有一些採用更高解析度、更奇葩的比例、或非常見的更高dpi的手機,此時就可能存在一個問題了,我們可愛好看的背景圖被無情的拉伸了,那麼這種問題如何解決呢?

以軟體開屏的閃屏圖為例,在16:9的手機上和19:9的手機上可能出現如下效果:

閃屏圖.png

顯然,我們一般的開發都是基於16:9的設備進行的,而在全面屏大行其道的今天,出現18:9,甚至19:9的手機也不足為奇,而這種情況下,我們閃屏頁的佈局中廣告圖部分的高度就發生了變化,正常方式下要麼出現上下白邊,要麼出現被拉伸,那麼這裡就要用到ImageView的屬性:

android:scaleType="centerInside"

使用此屬性的ImageView會以內等比例頂寬高縮放,以保證圖像能夠占滿佈局,而這裡也需要UI小姐姐們在出圖時盡可能避免內容貼邊的情況,這樣的適配就不會出現問題了。

尾巴

根據適合的業務邏輯採用適合的佈局架構可以輕鬆節省維護成本和構建時間,對於軟體的健壯性上都會有不錯的提升,重覆性勞動是我們在開發過程中最需要避免的,而良好的佈局基礎則是軟體能夠運營維護得更長遠的根本,此篇文章主要分享的是我在開發設計佈局中的一些見解,如果不對還希望大家多多指正,也希望大家養成良好的佈局習慣,做出更好用的軟體


●編號357,輸入編號直達本文

●輸入m獲取到文章目錄

推薦↓↓↓

Java編程

更多推薦18個技術類公眾微信

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂