為了更好地管理Android應用的用戶界面里的各組件,Android提供了布局管理器,通過使用布局管理器,Android應用圖形用戶界面具有良好的平臺無關性,推薦使用布局管理器來管理組件的分布、大小,而不是直接設定組件的位置和大小,可以使用布局管理器嵌套布局管理器,即也可作為一個UI組件來使用,
LinearLayout可以控制組件橫向排列或者縱向排列,內容不會換行,超出螢屏部分將不會顯示出來,
學習圖解

LinearLayout 常用XML屬性及方法
【屬性一】orientation 設定子組件的排列方式(單選)
XML: android:orientation="horizontal"

horizontal:橫向排列
vertical:縱向排列
JAVA :linearLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.HORIZONTAL 橫向排列

LinearLayout.VERTICAL 縱向排列

【屬性二】gravity 設定子組件的對齊方式(多選)
XML: android:gravity="center"

JAVA :linearLayout.setGravity(Gravity.CENTER);

【屬性三】baselineAligned 設定子元素基準線對棄,默認為true
基準線:
打開的英語練習本,那條紅線就是基準線


XML: android:baselineAligned="false"

JAVA: linearLayout.setBaselineAligned(true);
代碼:true
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_light"
android:padding="20dp"
android:text="text1"
android:textSize="30sp">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:padding="10dp"
android:text="text2"
android:textSize="16sp">
</TextView>
</LinearLayout>
效果:


【搭配屬性三】baselineAlignedChildIndex LinearLayout的基準線以他的第幾個子元素為準,下標從0開始
一個LinearLayout 里面有很多 textview ,每一個 textview 都有自己的基準線,那么LinearLayout可能也是另一個LinearLayout的子元素,作為子元素 baselineAlignedChildIndex 就決定這他的一個基準線
XML:android:baselineAlignedChildIndex="0"
JAVA:linearLayout.setBaselineAlignedChildIndex(0);
代碼:?注意內部的LinearLayout,后面將在 第二個LinearLayout上添加 baselineAlignedChildIndex ,搭配 baselineAligned="false" 使用
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_light"
android:text="這是text2"
android:textSize="20sp">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_light"
android:text="這是text1"
android:textSize="30sp">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_green_dark"
android:text="這是text2"
android:textSize="15sp">
</TextView>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="這是text4"
android:textSize="25sp"
android:background="@android:color/holo_orange_light"
>
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:text="text"
android:textColor="@android:color/white"
android:textSize="15sp">
</TextView>
</LinearLayout>
效果:




? 總結
- 默認LinearLayout是沒有基準線的,從圖一和圖三的對比可知,
- 下標從0開始三個子組件,最大index為2,超過2時布局將不顯示
- 這個屬性是用來決定當前LinearLayout的基準線時以哪個子組件為準的
??思考1:如果搭配 baselineAligned="true" 是什么樣的效果?
代碼:(修改上方代碼)

效果:




?總結
好像已經把上方的總結都打亂了,但是對比 baselineAligned="false" 的效果,可以發現,其實LinearLayout 的基準線其實還是在 baselineAligned="false" 時對應子組件的基準線位置為準的,可以參考 text4 和text5 的位置,他們所對棄的基準線,不是 前三個 text 變化后位置的基準線,而是變化之前的基準線位置,
??思考2:基準線時平行的,如果設定 LinearLayout 子組件為縱向排列那還有效果嗎?
答:沒有效果沒有變化

【屬性四】divider 分割線
我第一次遇到這個divider 是在 ListView 中
??代碼
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/colorPrimary"
android:dividerHeight="3dp">
</ListView>
??效果

?注意這里 divider 必須和 dividerHeight 才能顯示出效果,于是憑借經驗,你以為在LinearLayout也能如此,那就入坑了
XML: android:divider="@mipmap/ic_launcher"
??必須使用圖片或者是shape檔案,不能直接和ListView一樣直接使用顏色(會導致沒效果)
??需要搭配 showDividers 使用才有效果
JAVA: linearLayout.setDividerDrawable(getResources().getDrawable(R.mipmap.ic_launcher));
【關鍵屬性四】 showDividers 分割線顯示的位置(可多選)

XML: android:showDividers="middle|beginning"
JAVA:linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
??關鍵代碼 :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@mipmap/ic_launcher"
android:showDividers="middle|beginning"
android:orientation="horizontal">
<···/>
</LinearLayout>
??效果:

使用shape 分割
創建 linear_line.xml

將 selector 修改成shape,如下
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="5dp" android:width="5dp"/> <solid android:color="@android:color/holo_purple" /> </shape>
??這里要使用 size 來定義 線的一個寬度 width 作為橫向的分割線,如果是縱向的就要定義一個 高度 height
android:divider="@drawable/linear_line"
android:showDividers="middle|beginning"
??效果:三種可以相互組合



【搭配屬性四】dividerPadding 分割線的padding
XML: android:dividerPadding="10dp"
JAVA:linearLayout.setDividerPadding(10);
??代碼:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/linear_line"
android:showDividers="middle"
android:dividerPadding="10dp"
android:orientation="horizontal">
</LinearLayout>
??效果:


?總結
- 默認分割線的高度或寬度是和LinearLayout 布局管理器大小一致
- 如果是橫向布局,shape 中設定的 height 對顯示沒有影響
- 可以發現如果是橫向排列只影響縱向的padding,縱向則影響橫向的padding
LinearLayout 子組件的特殊屬性
所有子組件都受 LinearLayout.LayoutParams 控制
【屬性一】 layout_gravity 設定自身在布局管理器中的位置
??上方講解到了gravity,其gravity不是LinearLayout 的特有屬性,但layout_gravity 是其子組件的特殊屬性,具體區別請參考我的博客 layout_gravity和gravity的區別:https://www.cnblogs.com/xqz0618/p/gravity.html,這里不再詳細說明

【屬性二】layout_weight 權重 ??(重要屬性)
這是LinearLayout 及其重要的一個屬性,根據權重來設定子組件的在整個螢屏的占比,能夠達到很好的適配螢屏的效果
代碼:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/linear_line"
android:baselineAligned="false">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_light"
android:text="text1"
android:textSize="20sp">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@android:color/holo_red_light"
android:text="text2"
android:textSize="30sp">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="@android:color/holo_green_dark"
android:text="text3"
android:textSize="15sp">
</TextView>
</LinearLayout>
??這里是橫向布局,將對 layout_width 進行修改得到不同的結果
情況一:將 layout_width 全部設定成 0dp,權重分別是1:2:3,設定0dp后必須使用權重才不報錯

?可以看出來 三個text 的寬度在誤差范圍內是和weight權重相同的 1:2:3,所以單個text 的寬度計算就為:
假設螢屏的寬度為P,單個子組件的大小為W,子組件的權重之和為G,該組件設定的權重為H
則 W = H/G*P
即當前 1:2:3
W = H/G*P = 1/(1+2+3)*P = 1/6P
text1占比為螢屏的 1/6
情況二:將 layout_width 全部設定成 wrapcontent

??情況二并沒有像情況一一樣,根據權重的比例 1:2:3,按照情況1的公式就不成立
?實際上權重是根據總螢屏的大小 P減去所有子組件的 layout_width 然后再根據權重進行分配的大小再加上 layout_width,這里說有點亂了,看分析,

??用控制元件的大小減去文本的大小得到的寬度,考慮誤差范圍內,其實是 1:2:3的
假設螢屏的寬度為P,單個子組件的大小為W,子組件的權重之和為G,該組件設定的權重為H,子組件的layout_width為L
則 W = H/G*(P-3L)+L
即當前 1:2:3
text1的螢屏占比 W =H/G*(P-3L)+L = 1/(1+2+3)*(P-3L)+L
這里使用 wrap_content不好計算
反過來思考 當 L=0dp 時
W = 1/(1+2+3)*(P-0)+0= 1/6P
與上方結果一致
情況三:將 layout_width 全部設定成 match_parent

從上圖可以看出 text1和text2 比例分別為 2:1,text3不見了,用上方的式子驗證:
假設螢屏的寬度為P,單個子組件的大小為W,子組件的權重之和為G,該組件設定的權重為H,子組件的layout_width為L
則 W = H/G*(P-3L)+L
即當前 1:2:3
由于此時 layout_width是match_parent,則 L= P
text1的螢屏占比 W =H/G*(P-3L)+L = 1/(1+2+3)*(P-3L)+L=1/(1+2+3)*(P-3P)+P = 1/6*(-2P)+P= 2/3P
由此
text2的 W = 1/3P
text3的 W = 3/(1+2+3)*(-2P)+P = 0dp
那也就是說text3并不是超出螢屏沒顯示,而是他的寬度就是為0 //可以添加一個滾動控制元件來驗證一下
?總結
我們得到的統一公式,來計算這個螢屏占比問題(其實話說回來,你整這么麻煩干嘛,直接使用0dp不爽嗎,當然一些場景可能需要 warpcontent)
假設螢屏的寬度為P,單個子組件的大小為W,子組件的權重之和為G,該組件設定的權重為H,子組件的layout_width為L
則 W = H/G*(P-3L)+L
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/18540.html
標籤:Android
上一篇:Android 智能手機開發概述
