Android LinearLayout 各布局属性总结

LinearLayout是开发中使用率很高的控件,大部分开发人员感觉应该是很熟悉了,不过LinearLayout还有如下几个需要注意的地方,深刻了解以下几点可以让我们更加全面地认识LinearLayout的真正功能,避免开发中不自觉的踩坑。

一、当父控件orientation为vertical时,只有水平方向的设置才起作用,垂直方向的设置不起作用。即:left、right、center_horizontal 是生效的;top、bottom、center_vertical是无效的。

       当父控件的orientation为horizontal时,只有垂直方向的设置才起作用,水平方向的设置不起作用。即:top、bottom、center_vertical是生效的;left、right、center_horizontal是无效的。

原因如下:

我们可以直接看一下LinearLayout的源码布局:

其中layoutVertical(l,t,r,b)方法中关键代码如下:

for循环是绘制子布局,switch语句是根据gravity的值确定水平方向的起始位置,三种值分别为:LEFT,CENTER_HORIZONTAL和RIGHT,由此可以看出只有水平方向的设置起作用。

二、当LinearLayout水平布局且设置gravity="bottom"的时候,其多个子控件的底部的其实是在一条水平线上的欢迎讨论):

先看代码:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_blue"
    android:gravity="bottom"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:background="@color/colorAccent"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="呵呵"/>

</LinearLayout>

本来我以为的布局效果是这样的:

其实的布局效果是这样的:

所以能看出来,当两个子布局的底部还是需要保持在一条水平线上的,如有疑问,欢迎讨论。

三、layout_weight属性:真正意义表示“剩余”空间的占比

1、当LinearLayout的两个子控件的width都是wrap_content时,且layout_weight分别为1和2:

  • 那么tv1所占的空间=[总空间-(tv1的字体空间 + tv2的字体空间)] /(1+2)*1 + tv1的字体空间。
  • 同理tv2所占的空间=[总空间-(tv1的字体空间 + tv2的字体空间)]/(1+2)*3 + tv2的字体空间。

布局效果:

代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_red"
    android:gravity="bottom"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/color_green"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:background="@color/color_blue"
        android:text="呵呵"/>

</LinearLayout>

2、上面给人的感觉是当weight越大时所占有空间越大,其实不是这样子的,当我们将两个子控件的width都设置成math_parent时,且layout_weight依然分别为1和2时:

布局效果:

代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_white"
    android:gravity="bottom"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/color_green"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:background="@color/color_blue"
        android:text="呵呵"/>

</LinearLayout>

这表示tv1和tv2开始都占有屏幕的宽度大小,假如屏幕宽度为1080,那么"剩余"空间的占比变为1080-1080*2 = -1080.

所以tv1占有的空间为:1080 +[-1080/(1+2)]*1=720

tv2占有的空间为:1080+[-1080/(1+2)]*2=360

很明显tv1看起来比tv2占有的空间大。

所以weight值的大小跟所占有的空间大小没有必然的联系。

3、假如我们要做一个自适应的布局,左右两个按钮,可以根据屏幕的大小适应,左按钮始终最左边,右按钮始终在最右边。

效果如下:

当我们使用RelativeLayout的时候很容易实现,即分别设置设置layout_alignParentLeft="true"layout_alignParentRight="true"就可以了。

但当我们使用LinearLayout如何很快就这种效果呢,这里使用到了Space属性,将此空间放置中间,并只设置其layout_weight 为1,即中间剩余空间都由该Space撑满。

代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_white"
    android:gravity="bottom"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:text="哈哈"/>

    <Space
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/color_black"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="呵呵"/>

</LinearLayout>

4、weightSum属性:其与weight属性有很大关系,可通过weightSum控制weight的最大占比(假设字体占有空间宽度为120,屏幕宽度为1080)。

*当weightSum为3,子控件weight分别为1时:

效果如下:

tv1与tv2本来是一样的weight,可是结果它们都没有撑满屏幕。因为weightSum="3",也就是说tv1、tv2占用的宽度是 120 + 840 / 3 = 400 ,右边还有剩余280。

代码如下:


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_white"
    android:gravity="bottom"
    android:orientation="horizontal"
    android:weightSum="3">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/colorAccent"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="@color/colorPrimary"
        android:text="呵呵"/>

</LinearLayout>

*当weightSum为3时,子控件weight分别为2时:

效果如下:

tv1与tv2本来是一样的weight且为2。此时weightSum="3",也就是说tv1、tv2占用的宽度是 120 + 840 * 2 / 3 = 680 ,两个都是 680,而屏幕宽度是1080,所以此时tv2被挤到屏幕之外了。

代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_white"
    android:gravity="bottom"
    android:orientation="horizontal"
    android:weightSum="3">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:background="@color/colorAccent"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:background="@color/colorPrimary"
        android:text="呵呵"/>

</LinearLayout>

三、divider showDivider属性

以往我在设置分割线时,都是新增一个View,用来显示分割线,直到我发现在LinearLayout中添加分割线的新方法。LinearLayout显示分割线主要涉及divider 、showDividers 属性 : android:divider用于设置分割线的样式,可以是xml的drawable也可以是图片。android:showDividers = "middle|end|beginning|none" 其每个选项的作用:

  • middle 在每一项中间添加分割线
  • end 在整体的最后一项添加分割线
  • beginning 在整体的最前方添加分割线
  • none 不显示分割线

效果如下:

代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/color_white"
    android:divider="@drawable/shape"
    android:gravity="bottom"
    android:orientation="horizontal"
    android:showDividers="beginning|middle|end">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:background="@color/colorAccent"
        android:text="哈哈"/>

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:background="@color/colorPrimary"
        android:text="呵呵"/>

</LinearLayout>

shape.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/holo_green_dark"/>
    <size
        android:width="2dp"
        android:height="12dp"/>
</shape>
发布了95 篇原创文章 · 获赞 195 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/u012440207/article/details/85076326