線性佈局線性佈局LinearLayout是最常用的佈局,顧名思義,它下麵的子視圖像是用一根線串了起來,所以其內部視圖的排列是有順序的,要麼從上到下垂直排列,要麼從左到右水平排列。排列順序只能指定一維方向的視圖次序,可是手機屏幕是個二維的平面,這意味著還剩另一維方向需要指定視圖的對齊方式。故而線性佈局 ...
線性佈局
線性佈局LinearLayout是最常用的佈局,顧名思義,它下麵的子視圖像是用一根線串了起來,所以其內部視圖的排列是有順序的,要麼從上到下垂直排列,要麼從左到右水平排列。排列順序只能指定一維方向的視圖次序,可是手機屏幕是個二維的平面,這意味著還剩另一維方向需要指定視圖的對齊方式。故而線性佈局主要有以下兩種屬性設置方法:
1. setOrientation: 設置內部視圖的排列方向。LinearLayout.HORIZONTAL表示水平佈局,LinearLayout.VERTICAL表示垂直佈局。
2. setGravity: 設置內部視圖的對齊方式。Gravity.LEFT表示靠左對齊、Gravity.RIGHT表示靠右對齊、Gravity.TOP表示靠上對齊、Gravity.BOTTOM表示靠下對齊、Gravity.CENTER表示居中對齊。
空白距離margin和間隔距離padding是另外兩個常見的視圖概念,margin指的當前視圖與周圍視圖的距離,而padding指的是當前視圖與內部視圖的距離。這麼說可能有些抽象,接下來還是做個實驗,看看它們的顯示效果到底有什麼不同。下麵是個實驗用的佈局文件內容,通過背景色觀察每個視圖的區域範圍:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <!-- 外層佈局的背景色是藍色 --> <LinearLayout android:layout_width="match_parent" android:layout_height="300dp" android:background="#00aaff" > <!-- 中間佈局的背景色是黃色 --> <LinearLayout android:id="@+id/ll_margin" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffff99" > <!-- 內層視圖的背景色是紅色 --> <View android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff0000" /> </LinearLayout> </LinearLayout> </LinearLayout>
與上述佈局文件對應的頁面Kotlin代碼如下,根據不同的按鈕分別設置不同方向上的margin和padding數值:
//該頁面用於演示margin和padding的區別 class LinearLayoutActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_linear_layout) //設置ll_margin內部視圖的排列方式為水平排列 ll_margin.orientation = LinearLayout.HORIZONTAL //設置ll_margin內部視圖的對齊方式為居中對齊 ll_margin.gravity = Gravity.CENTER btn_margin_vertical.setOnClickListener { //Kotlin對變數進行類型轉換的關鍵字是as val params = ll_margin.layoutParams as LinearLayout.LayoutParams //setMargins方法為設置該視圖與外部視圖的空白距離 //此處設置左邊和右邊的margin空白距離為50dp params.setMargins(0, dip(50), 0, dip(50)) ll_margin.layoutParams = params } btn_margin_horizontal.setOnClickListener { val params = ll_margin.layoutParams as LinearLayout.LayoutParams //此處設置頂部和底部的margin空白距離為50dp params.setMargins(dip(50), 0, dip(50), 0) ll_margin.layoutParams = params } //setPadding方法為設置該視圖與內部視圖的間隔距離 btn_padding_vertical.setOnClickListener { //此處設置左邊和右邊的padding間隔距離為50dp ll_margin.setPadding(0, dip(50), 0, dip(50)) } btn_padding_horizontal.setOnClickListener { //此處設置頂部和底部的padding間隔距離為50dp ll_margin.setPadding(dip(50), 0, dip(50), 0) } } }
依據頁面代碼例子,Kotlin代碼與Java代碼的寫法有以下三點區別:
1. Kotlin允許對屬性orientation直接賦值,從而取代了setOrientation方法;類似的還有屬性gravity取代了setGravity方法;
2. Kotlin使用關鍵字as進行變數的類型轉換;
3. Kolin支持調用dip方法將dip數值轉換為px數值,倘若由Java編碼則需開發者自己實現一個像素轉換的工具類;
因為dip方法來自於Kotlin擴展的Anko庫,所以需要在Activity代碼頭部加上下麵一行導入語句:
import org.jetbrains.anko.dip
既然用到了Anko庫,自然要修改模塊的build.gradle,在dependencies節點中補充下述的anko-common包編譯配置:
compile "org.jetbrains.anko:anko-common:$anko_version"
Anko庫除了提供dip方法,還提供了sp、px2dip、px2sp、dimen等像素單位的轉換方法,具體的方法說明見下表。
dip 將dip單位的數值轉換為以px為單位的數值
sp 將sp單位的數值轉換為以px為單位的數值
px2dip 將px單位的數值轉換為以dip為單位的數值
px2sp 將px單位的數值轉換為以sp為單位的數值
dimen 將dip單位的數值轉換為以sp為單位的數值
相對佈局
由於線性佈局的視圖排列方式比較固定,既不能重疊顯示也不能靈活佈局,因此複雜一些的界面往往用到相對佈局RelativeLayout。相對佈局內部的視圖位置不依賴於排列規則,而依賴於指定的參照物,這個參照物可以是與該視圖平級的視圖,也可以是該視圖的上級視圖(上級視圖即相對佈局自身)。有了參照物之後,還得指定當前視圖位於參照物的哪個方向,才能確定該視圖的具體位置。
在代碼中指定參照物及其所處方位,調用的是佈局參數對象的addRule方法,方法格式形如“addRule(方位類型, 參照物的資源ID)”。下麵是個給相對佈局添加下級視圖的Kotlin代碼例子:
//根據參照物與方位類型添加下級視圖 private fun addNewView(align: Int, referId: Int) { var v = View(this) v.setBackgroundColor(Color.GREEN) val rl_params = RelativeLayout.LayoutParams(100, 100) rl_params.addRule(align, referId) v.layoutParams = rl_params v.setOnLongClickListener { vv -> rl_content.removeView(vv); true} rl_content.addView(v) }
代碼里的方位類型有多種取值,比如RelativeLayout.LEFT_OF表示位於指定視圖的左邊,RelativeLayout.ALIGN_RIGHT表示與指定視圖右側對齊,RelativeLayout.CENTER_IN_PARENT表示位於上級視圖中央等等。舉個例子,讓某視圖位於指定視圖上方,且與上級視圖的左側對齊,則調用addRule方法的Kotlin代碼如下所示:
rl_params.addRule(RelativeLayout.ABOVE, 指定視圖的資源ID) rl_params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 上級視圖的資源ID)
由此可見,常規的addRule調用代碼有點冗長,因此Kotlin利用Anko庫將相對位置進行了簡化,具體辦法是引入擴展函數實現相對位置的設定,譬如above方法代表位於指定視圖上方,alignParentLeft方法代表與上級視圖的左側對齊。於是原來的Kotlin代碼簡化如下:
rl_params.above(指定視圖的資源ID) rl_params.alignParentLeft()
因為這幾個新方法來自於Anko庫,所以要在代碼頭部加上下麵一行導入語句:
import org.jetbrains.anko.*
另外要修改模塊的build.gradle,在dependencies節點中補充下述的anko-common包編譯配置:
compile "org.jetbrains.anko:anko-common:$anko_version"
除了above和alignParentLeft之外,Anko也提供了所有的相對位置設定方法,具體的對應關係說明見下表。
Anko庫的相對位置 RelativeLayout類的相對位置
leftOf LEFT_OF
sameTop ALIGN_TOP
above ABOVE
sameLeft ALIGN_LEFT
rightOf RIGHT_OF
sameBottom ALIGN_BOTTOM
below BELOW
sameRight ALIGN_RIGHT
centerInParent CENTER_IN_PARENT
alignParentLeft ALIGN_PARENT_LEFT
centerVertically CENTER_VERTICAL
alignParentTop ALIGN_PARENT_TOP
centerHorizontally CENTER_HORIZONTAL
alignParentRight ALIGN_PARENT_RIGHT
alignParentBottom ALIGN_PARENT_BOTTOM