本人CSDN博客 https://blog.csdn.net/qq_37120167/article/details/84395936
最近弄的一個項目中涉及到了權重,因為沒有設置寬高為0dp耽誤了我兩天的工程,哎想想也真是好笑,被自己蠢死了。今天上網查看了很多博客了解到一些,然后自己動手弄了一下下,收獲了很多,感覺自己以前還是太簡單,學習真是要吃透才行,不能一知半解,真的是很坑。寫這篇博客就是想記錄一下自己研究出來的東西,並不一定准確,但是可以借鑒一下,要是我說的哪里不對希望給予一些建議,萬分感謝。
通過查找資料感覺很多人不理解,設置權重時,即使不設置width(或height)為0dp也可以達到效果,那為什么還要設置width(或height)為0dp呢?
是這樣的,系統會先根據width和height屬性首次對控件進行排版,然后在查看是否分配了權重,在按照權重二次分配控件。這樣就執行了兩次。如果將width(或height)為0dp就執行一次就可以了,提高運行性能。
既然不設置為0dp也可以,那就沒什么區別吧?
其實不是的,有時可能沒有影響,也會達到你想要的效果,但是其中的實際意義一定是不同的。
1、公式
首先上核心內容:控件所占空間公式
實際所占空間 = 設定的寬高所需空間 + 所占剩余空間的百分比
現在着重講解一下這個公式
這里我們先設定一下父容器的寬或高(也就是指屏幕的寬或長度)的長度值為L
這里有三個重點也是難點需要理解,從難到易依從為:
1)剩余空間
2)百分比
3)設置的寬或高的填充形式(此處指:match_parent即為L 或wrap_content或0dp等)
【詳細解釋】
1)剩余空間
其中最不好理解也是最重要的一個概念就是“剩余空間”,這里說的是用父容器的長度值(也就是我們自己定義的L) 減去 每個控件需要占用父容器的長度之和的值。比如說你在一個布局中有三個Button控件水平放置,那我們的關注點就是width的值,btn1的width為match_parent(就是我們自定義的L),btn2的width也設置為match_parent(就是我們自定義的L),btn3的width還設置為match_parent(就是我們自定義的L),那么剩余空間的值為:父容器的長度(就是我們設定的L)- btn1的width的值(就是我們設定的L)-btn2的width的值(就是我們設定的L)-btn3的width的值(就是我們設定的L)= L-L-L-L=L-3L=(1-3)L=-2L
我們求得剩余空間的值為-2L,似的你沒有看錯,就是負的,-2L。到這里你可能還是不是很理解,不重要,接下會用實例在講解一下。
2)百分比
然后在說百分比,就是被分配的權重數比上權重值的和。比如說你在一個布局中有三個Button控件,btn1分配到的權重值為1,btn2分配到的權重值為2,btn3分配到的權重值為3,那么btn1所占剩余空間的百分比就是1/(1+2+3)=1/6,btn2所占剩余空間的百分比就是2/(1+2+3)=1/3,btn3所占剩余空間的百分比就是3/(1+2+3)=1/2,你現在理解百分比是怎么求的了吧。
3)設置的寬或高的填充形式(此處指:match_parent即為L 或wrap_content或0dp等)
最后說一說這里提到的“設置的寬或高的填充形式”有三個:
第一種是match_parent(低版本里是fill_parent,就是名字不一樣了東西還是一個)就是指占滿父容器此時要控件的寬或高等於父容器的寬或高(即為L)。
第二種wrap_content是指控件的高或寬隨內容的長度決定。
第三種是設置固定值,可以是30dp,也可以是120dp,想要設置為0dp,必須有weight屬性,且值不為0才可以。
好了公式講完了,不知道你理解的怎么樣,下面舉例說明一下,希望能更清晰。
2、結合實例
我們主要以水平分布為主,垂直情況與之類似。
2.1 LinearLayout(線性布局)
情況一:三個Button水平分布,btn1、btn2的width為0dp且weight為1,btn3的width為match_parent沒有分配權重,btn3位於最右側。
【源代碼2.1.1】
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
【計算占用空間】
我們先求出剩余空間:
剩余空間 = 父容器的長度(就是我們設定的L)- btn1的width的值(此處為0dp所以值為0 )-btn2的width的值(此處為0dp所以值為0)-btn3的width的值(match_parent就是我們設定的L)= L-0-0-L=L-L=0
btn1實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = 0 + 1/(1+1)*0 = 0
btn2實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = 0 + 1/(1+1)*0 = 0
btn3實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = L + 0 = L (因為沒有分配權重所以不涉及到所占剩余空間的百分比)
到這里有沒有理解一些了,不急,我們繼續。
情況二:三個Button水平分布,btn1、btn2的width為0dp且weight為1,btn3的width為match_parent沒有分配權重,btn3位於中間。
【源代碼2.1.2】
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
【計算占用空間】
同上。
情況三:三個Button水平分布,btn1、btn2的width為0dp且weight為1,btn3的width為match_parent沒有分配權重,btn3位於最左側。
【源代碼2.1.3】
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
【計算占用空間】
同上。
【發現總結】
我覺得LinearLayout之所以會因為btn3的位置發生改變而產生了不同的效果跟LinearLauout的特性有關,它自身有種類似代碼執行時順序結構的執行方式的感覺,從左向右捋,依次響應,當然是我個人的判斷而已。
【結語】
今天仔細查閱並結合實例運行查看效果感觸頗深,所以一定要打出來看效果理解的才更深刻,還會有新發現,實踐出真知!!
最后再寫一個例子鞏固一下吧
情況一:三個Button水平分布,按鈕的width屬性都為match_parent,btn1的權重為1,btn2、btn3的權重都為2。
【源代碼】
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
【計算占用空間】
我們先求出剩余空間:
剩余空間 = 父容器的長度(就是我們設定的L)- btn1的width的值(此處為match_parent即值為L)-btn2的width的值(此處為match_parent即值為L)-btn3的width的值(此處為match_parent即值為L)= L-L-L-L=L-3L=-2L
btn1實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = L + 1/(1+2+2)*(-2L) = L-2/5L=3/5L
btn2實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = L + 2/(1+2+2)*(-2L) = L-4/5L=1/5L
btn3實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = L + 2/(1+2+2)*(-2L) = L-4/5L=1/5L
如上圖顯示效果btn1所占空間是btn2所占空間的3倍、同樣也是btn3所占空間的3倍。
情況二:三個Button水平分布,按鈕的width屬性都為0dp,btn1的權重為1,btn2、btn3的權重都為2。
【源代碼】
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="2" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_weight="2" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
【計算占用空間】
我們先求出剩余空間:
剩余空間 = 父容器的長度(就是我們設定的L)- btn1的width的值(此處為0dp即值為0)-btn2的width的值(此處為0dp即值為0)-btn3的width的值(此處為0dp即值為0)= L-0-0-0=L
btn1實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = 0 + 1/(1+2+2)*L = 1/5L
btn2實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = 0 + 2/(1+2+2)*L = 2/5L
btn3實際占用空間 = 設定的寬高所需空間+ 所占剩余空間的百分比 = 0 + 2/(1+2+2)*L = 2/5L
如上圖顯示效果btn2、btn3所占空間都是btn1所占空間的2倍。
情況三:三個Button水平分布,按鈕的width屬性都為match_parent,btn1的權重為1,btn2的權重為2,btn3的權重為3。
【源代碼】
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <Button android:text="A" android:id="@+id/btn1" android:background="#FFC125" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="B" android:id="@+id/btn2" android:background="#F08080" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:text="C" android:id="@+id/btn3" android:background="#BFEFFF" android:layout_weight="3" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
【效果圖】
這里我就不算了,你可以試着講width的屬性值都改為0dp在看看,效果又不一樣哦,希望能幫到你