美文网首页android安卓基础知识View
你真的了解android:layout_weight 吗?

你真的了解android:layout_weight 吗?

作者: IAM四十二 | 来源:发表于2016-04-12 22:47 被阅读7084次

一直以来对android:layout_weight 属性的理解停留在对其相对于的View按权重(或者说是比例)平分的概念中,因为之前学习时看的书上就是这么讲的。最近才发现原来不仅仅是按权重平分那么简单(真是坑爹教材坑死人啊),严格的说法应该是对当前剩余空间按权重平分

初探##

日常开发中,在LinearLayout中使用layout_weight可以很好的应对那些内容会动态变化的布局结构。比如表单填写,最常见的就是注册登录页面布局内容的实现,例如要实现下图布局

layout_weight

可用如下方式实现

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
    android:layout_marginTop="10dp"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:padding="8dp"
        android:layout_width="0dp"
        android:layout_weight="1.5"
        android:layout_height="wrap_content"
        android:text="用戶名"
        android:gravity="center"
        android:id="@+id/textView2" />

    <EditText
        android:padding="8dp"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text=""
        android:ems="10"
        android:id="@+id/editText"
        android:layout_weight="3" />
</LinearLayout>

    <LinearLayout
        android:layout_marginTop="10dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:padding="8dp"
            android:layout_width="0dp"
            android:layout_weight="1.5"
            android:layout_height="wrap_content"
            android:text="密码"
            android:gravity="center"
            />

        <EditText
            android:padding="8dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:inputType="textPersonName"
            android:text=""
            android:ems="10"
            android:layout_weight="3" />
    </LinearLayout>
    <LinearLayout
        android:layout_marginTop="10dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:padding="8dp"
            android:layout_width="0dp"
            android:layout_weight="1.5"
            android:layout_height="wrap_content"
            android:text="确认密码"
            android:gravity="center"
             />

        <EditText
            android:padding="8dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:inputType="textPersonName"
            android:text=""
            android:ems="10"
            android:layout_weight="3" />
    </LinearLayout>

</LinearLayout>

这里使TextView和EditText的宽度为0,让后使其权重分别为1.5和3,这样整体效果会看起来比较整齐,当然用RelativeLayout也是能实现的,但是这样更简单一些,也更高效。

进阶##

在Android没有推出android-percent-support-lib之前,甚至在其推出后,一直使用layout_weight实现“百分比”布局。相比于wrap_content和match_parent ,巧妙的使用layout_weight可以很简洁的实现界面按“百分比”布局,当然这其中也有一些奥妙,这里就做一下记录。

首先看一下下面的布局文件

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

    </LinearLayout>

这段代码实现的UI效果如下:

layout_weight

整个布局是个垂直的LinearLayout,里面有三个水平方向的LinearLayout,内部放置了三个TextView,三个TextView高度为wrap_content;其内容和背景色也不同(这里只是为了看起来方便),重点是其宽度:

  • 第一行内三个TextView
layout_width="wrap_content"
  • 第二行内三个TextView
android:layout_width="match_parent"
  • 第三行内三个TextView
android:layout_width="0dp"

每一个LinearLayout内部三个TextView的layout_weight分别1,2,3。由此,看见由于其wrap_content的不同,使其layout_weight的分配受到了影响。这里就来分析一下,按照之前所说,layout_weight会按屏幕剩余空间,按权重分配空间。

  • 第一种情况(第一个LinearLayout)

系统先给3个TextView分配他们的宽度值wrap_content(宽度足以包含他们的内容1,2,3即可),然后会把剩下来的屏幕空间按照1:2:3的比列分配给3个textview,
上面的UI 比重为 :
61/6 ,62/6,6*3/6 即1:2:3 ,如UI 第一行呈现的那样。

  • 第二种情况(第二个LinearLayout)

系统先给3个textview分配他们所要的宽度match_parent,也就是说每一都是填满他的父控件,这里就是屏幕的宽度
那么这时候的剩余空间=
1个parent_width-3个parent_width=-2个parent_width (parent_width指的是屏幕宽度 )

那么第一个TextView的实际所占宽度应该=match_parent的宽度,
即parent_width + 他所占剩余空间的权重比列1/6 * 剩余空间大小(-2 parent_width)=2/3parent_width

同理第二个TextView的实际所占宽度=parent_width + 2/6*(-2parent_width)=1/3parent_width;

第三个TextView的实际所占宽度=parent_width + 3/6*(-2parent_width)=0parent_width;所以就是2:1:0的比列显示了。

即如UI第二行呈现的那样。

  • 第三种情况

这种情况,其实和第一种是一样的。

看到这里,下次使用layout_weight时,如果放置的控件看不见了,就不会觉得奇怪了。

举一反三##

好了,接下来想想,如果把上面代码里三个TextView的权重依次改为3,2,1 又会是一种怎样的UI效果呢,想好了,看下面代码和实际效果图。

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#FF424242"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:background="#77bc1f"
                android:text="AAA"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:background="#06d992"
                android:text="BBB"
                android:textColor="#fff"
                android:textSize="23sp" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#EEA32E"
                android:text="CCC"
                android:textColor="#fff"
                android:textSize="23sp" />
        </LinearLayout>

    </LinearLayout>
layout_weight

应该和你想的一样吧。

好了,这里就是对android:layout_weight的学习笔记,虽然是一个很简单的属性,但是巧妙的设置后,很方便的实现一些布局。


ps:markdown 语法什么时候直接支持代码高亮,加粗就好了

相关文章

网友评论

  • 4f524c2e2ec8:文章写的很好,但是文章读下来 觉得第一个跟第三个是不一样的吧。假设屏幕宽度为m,文字的宽度是n(例子里面文字的宽度是一致的),那么,第一个的 LinearLayout 里面 textview 的实际宽度比例为 n+1/6(m-3n),n+2/6(m-3n),n+3/6(m-3n)。故,不是1:2:3。第三个的 LinearLayout 里面 textview 的实际宽度比例为 0+1/6(m-0),0+2/6(m-0),0+3/6(m-0)。故,是1:2:3。
    IAM四十二:嗯,说的很对,这两种从理论到实际效果的确是有区别的;直接设置为0时,能更加精准的实现想要的效果,也更好理解;日常开发中使用最后一种情况较多。
  • ania:第二种情况具体分析如下:看不懂的童鞋可以瞄两眼哈。
    假设屏幕宽度为1。那么三个控件占据后的剩余空间就是1-1*3=-2;
    然后将剩余的-2宽度屏幕控件按照1:2:3的比例分给三个控件。
    A:-2*(1/6)=-1/3 ; 然后原来分配给控件的宽度为1;1+(-1/3)=2/3;故实际宽度为2/3
    B:-2*(2/6)=-2/3 ;同上,1+(-2/3)=1/3;故实际宽度为1/3
    C:-2*(3/6)=-1;同上,1+(-1)=0;故实际宽度为0
    keepKK:还有就是剩余空间分给三个空间是什么原理,为什么不是原本的空间去分,而是剩余的空间去分给各个权重,这个逻辑是哪里来的
    keepKK:@ppjun君 表示和你一样,不理解,这个算法是哪里有规定的
    ppjuns:看不懂1+(-1/3)=2/3;这个操作也,为什么是相加的,我理解是分配给控件的宽度1 乘以 剩余宽度的比例也就是1*-1/3
  • 雨桥明夜:得到很大的帮助,谢谢
  • 一个冬季:点赞,不错学习了
  • touchengine:不错,初学安卓,不过第一个代码框下面的“让后”应该是“然后”吧?
    IAM四十二: @touchengine 😂😂,都是输入法的错😃😃😃
  • hongjay:又多懂了一点,给您点赞ヾ(Ő∀Ő3)ノ太好惹
    IAM四十二: @HongJay 谢谢哦

本文标题:你真的了解android:layout_weight 吗?

本文链接:https://www.haomeiwen.com/subject/dgewlttx.html