本人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在看看,效果又不一样哦,希望能帮到你

 

版权声明:本文为ztybc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ztybc/p/9996609.html