設置權重時為什么要將width設置為0dp


  本人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 + 0L  (因為沒有分配權重所以不涉及到所占剩余空間的百分比)

到這里有沒有理解一些了,不急,我們繼續。

 情況二:三個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實際占用空間 = 設定的寬高所需空間+ 所占剩余空間百分比 = L1/(1+2+2)*(-2L) = L-2/5L=3/5L

btn2實際占用空間 = 設定的寬高所需空間+ 所占剩余空間百分比 = L2/(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實際占用空間 = 設定的寬高所需空間+ 所占剩余空間百分比 = 01/(1+2+2)*L1/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在看看,效果又不一樣哦,希望能幫到你

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM