线性布局的权重究竟是怎么一回事

写在前面

如果你是新手,我建议你坚持看下去,因为你肯定不了解权重,而权重并没有那么简单。希望看完后对你有一定的帮助。

关于说什么专业不专业,或者app流畅,其实不存在这回事情。设置成0dp,wrap-content,以及match-parent是有很多道理可循的。

关于布局

上节中我们讲了一些TextView的基本用法,那么这节我们就来讲一些Android中的常见布局。

Android早期主要有六大布局:分别是线性布局(LinearLayout),相对布局(RelativeLayout),帧布局(FrameLayout),绝对布局(AbsoluteLayout),表格布局(TableLayout)以及网格布局(GridLayout),随着Android的逐步发展,Android的布局也在随之增多,例如百分比布局(PercentLayout)以及约束布局(ConstraintLayout)等等。

今天我们主要讲解LinearLayout的常见用法,先来一张超大的思维导图。

根据上面的思维导图来看,上面的部分属性我们在之前的TextView中已经讲过了,所以在本节中我们主要讲一些LinearLayout的特有属性。

LinearLayout篇

常见属性讲解

  1. layout-width: 不过多说了,控件宽度,必要属性。
  2. layout-height: 同上,控件高度,必要属性。
  3. id: 定义资源id,以方便在Java源文件中通过findViewById(R.id.xx)生成该控件的实例。
  4. orientation: LinearLayout中的控件排列方向。两种选择,垂直(vertical)或者水平(horizontal), 反正劳资想怎么摆就怎么摆。

比如你可以这样摆:(水平方向)

你可以这样摆:(竖直方向)

“咦, 我的第二个TextView呢?怎么不见了?“

仔细看一下,TextView001的宽度填充了屏幕的宽高,你肯定是把TextView001的height属性设置成了match-parent(fill-parent)。劳资打破你的钛合金头,上节课不是跟你讲了吗?再检查看看。

”哎哟,果然是这样,赶紧换成wrap-content或者自定义标签,比如200dp。啊哈,好了。“

  1. background: 给控件设置背景颜色,这个我们上节已经讲过。

剩下还有两个属性:layout-gravity以及gravity,这个我们暂时不讲,留到后面再讲。

权重讲解

1.关于权重最基本的用法

我们首先还是先来看一下实现的效果

实现代码:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:background="#f00"
        android:layout_height="match_parent"
        android:text="LinearLayout爸爸,把你的位置分给我一半"/>
    <TextView
        android:background="#0f0"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:text="我也要,我也要"/>
</LinearLayout>

这个就是平分的效果。现在老大(红色)对老二(绿色)说:“你个小崽子,你比我小,我应该比你分得多。”然后就有了下面的效果。来来来,我们来上图。(我就是图,听说你们谁要上我?)

实现代码:

 <LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_weight="2"
        android:layout_width="0dp"
        android:background="#f00"
        android:layout_height="match_parent"
        android:text="LinearLayout爸爸,把你的位置分给我一半"/>
    <TextView
        android:background="#0f0"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:text="我也要,我也要"/>
</LinearLayout>

肯定有人说,你这代码都是一样的,你个傻吊,代码贴两遍。嗯?不忙,你仔细看看图,真的是一样的嘛?结果逐行对比一看,你会发现上面的两个例子中,只有一行代码是有区别的。在红色的TextView

中出现了这样的代码,如下:

第一张图片中的红色区域
android:layout_weight="1"
第二张图中的红色区域
android:layout_weight="2"

就一个“1”和“2”的区别,为什么会这样呢?

首先,我们讲一下第一个图中是怎么来的,根据图的效果,我们可以看到老大(红色)和老二(绿色)平分了屏幕的宽度,我们分别看一下两个TextView中是如何定义的?逐行对比你会发现,他们两个中都定义了

android:layout_weight = "1"

这个属性。“难道是?”,“嗯,悟性还不错!没错,就是这样。因为他们每个中都定义了weight属性的值为1,所以总的份数就是1+1 = 2(有两个TextView有weight为1的属性),而他们每个weight定义都为1,所以单个TextView的占总数比恰好等于1/2,老大占1/2,老二也占1/2,这与我们上面的第一个图恰好吻合。所以他们的一半一半就是这么来的!”

知道了第一张图的根本原因,那么我想第二个图也就不难解释了。总的份数是1 + 2 = 3,老大(红色)占比2/3, 老二(绿色)占比1/3。不难吧,如果不难的话,我们进入下面的学习。(ps:竖直方向你们就自己去折腾,和水平方向一样一样的)

2.weight属性的详解

”上面的权重情况很好理解吧?“

”何止是简单,简直简单的不像话?这属性有什么可说的?你这完全是没必要讲,正常人都能够理解。。“

“嗯,好的。你这只是片面的理解。那我们接下来看看你口中所谓的简单权重的另外一种情况。”

不知道你注意没有,在水平方向平分的情况下,上面的情况我们都只是设置了TextView的宽度全部都为0dp的情况下,不知道你考虑过一个问题没有,如果我们将TextView的高度不设置成0dp,设置成wrap-content,match-parent或者自定义的情况,那结果还是那样吗?

注意: 当我们在水平方向上使用weight属性的时候,控件所占屏幕比和控件的高度本身没有任何关系,只是和高度的值有关系。

“你说的是不是真的呀,我怎么觉得你是个假的大佬?”

“嗯,不信,没关系,俗话说:Talk is cheap, show me the code! ”

下面我们来看一段代码

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_weight="1"
        android:layout_width="wrap_content"
        android:background="#f00"
        android:layout_height="match_parent"
        android:text="总的份数是3, 我的权重为1,所以我占总分数的 1/3"/>
    <TextView
        android:layout_weight="1"
        android:background="#0f0"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="总的份数是3, 我的权重为1,所以我占总分数的 1/3"/>
    <TextView
        android:layout_weight="1"
        android:background="#00f"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="总的份数是3, 我的权重为1,所以我占总分数的 1/3"/>
</LinearLayout>

总的份数是3份,里面有3个TextView,每个TextView的权重都为1,这里我们将TextView的高度设置成了wrap-content。下面我们看看效果图。

显然和上面推断一样,正常的不能再正常了。好,那么我们将高度换成“match-parent”试试。

吃鲸,也一样。

”你真的不是一个假的大佬么?轻蔑脸.png,玩蛋去吧,傻吊。我懒得陪你了。“

”慢着,你再看看下面的这段代码?“

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:background="#f00"
        android:layout_height="match_parent"
        android:text="总的份数是6, 我的权重为1,所以我占总分数的 1/6"/>
    <TextView
        android:layout_weight="2"
        android:background="#0f0"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="总的份数是6, 我的权重为2,所以我占总分数的 2/6"/>
    <TextView
        android:layout_weight="3"
        android:background="#00f"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="总的份数是3, 我的权重为3,所以我占总分数的 3/6"/>
</LinearLayout>

”这么简单的问题,你别再烦我了,行不行。lowbee?红色占1/6,绿色占2/6,蓝色占3/6。“

”你确定吗?注意我们的宽度不再是0dp了,而是match-parent了!!!“

”这有什么不确定的?你傻我可不傻。哼!“

我们看看图:

咦,明明是1:2:3的比例,怎么会出现这样的结果?蓝色部分去哪里了?代码里面明明还有一个蓝色的部分的呀,而且蓝色部分占的比例最高,怎么会一点都没有了?原本1:2:3的比例现在却变成了2:1:0。为什么会出现这样的情况呢?其实权重没有那么简单的。当我们水平方向上设置权重的时候并且高度设置成match-parent的时候,权重会出现“反比例解析”的问题。

”别再自以为是了,你以为你真的了解权重么?“

所以,权重没那么简单。在水平方向上使用权重,还是要分情况进行计算的,他们分别都有自己对应的公式。所以别太天真,咱们都是成年人。首先我们讨论一下wrap-content和match-parent两种情况:(以下举例都是在水平方向使用权重,也就是改变控件的宽度情况下)

  1. 当控件的宽度设置成wrap-content的情况下,也就是android:layout-width=“wrap-content”的情况下

    控件的宽度 = ((控件的宽度 - 所有控件的宽度和)* 控件所占的权重) / 总的权重数 + 自身的宽度

  2. 当控件的宽度设置成match-parent的情况下,也就是android:layout-width=“match-parent”的情况下

    控件的宽度 = ((控件的宽度 - 所有控件的宽度和) * 控件所占的权重) / 总的权重数 + 自身的宽度

举个例子吧。利用一下数学知识,假设宽度为x, 里面有三个TextView,他们的宽度也分别为x,

那么weight为1的TextView实际占比例为:

y = ((x - 3x) * 1)/6  + x = 2x/3

接着我们计算weight为2的TextView实际占比为:

y = ((x - 3x) * 2)/6 + x = 1x/3;

他们两者加起来就已经等于了x,而x正好是屏幕的宽度,所以第三个权重占比为3的蓝色TextView自然也就不会展示出来了。而红色TextView和绿色TextView的实际比例却是2:1,这也与我们上面的图片结论相吻合。

关于权重,不同的写法会有不同的效果,例如我们刚才只是讨论了控件相同的情况,不知道你想过没有,如果控件不同呢?又是一个什么情况?比如下面的例子?

你们应该都能够看出来这绝对不是平分的效果,至于为什么,我提示一下。

在控件不同,实际上LinearLayout是分两个步骤来设置视图宽度的。
第一步,LinearLayout会查看layout-width属性值。
第二步,LinearLayout才会依据layout-weight属性值进行额外的空间分配。

还有一些情况,需要你们自己去摸索,我就不在这里说了,毕竟篇幅太多了,我相信能够看到这里的人并不多。所以这里就不展开了。

分割线

你们肯定在实际情况中,经常会看到这样的界面?

细心的你观察到界面的变化没有,我们姑且称每一个条目为一个Item,那么每一个Item下面都有一条对应的分割线,是不是?不要跟我说你没看到,你瞎呀你,没看到。这么明显。。至于这个分割线是怎么做出来的呢?我这里可以说有n多办法。

  1. 比如用图片,图片可以是一条分割线。
  2. 比如用layout-marginTop = 1dp或者layout-margin = 0.5dp的方式。
  3. 比如用shape。
  4. 比如用LinearLayout的divider。
  5. 比如用LinearLayoutCompat的deividr。

这都是办法,只要你想做,方法一定比困难多,相信我。但是今天我们主要讲dividr,所以我们这里就不详细说如下的几种情况了。只是单纯说一下LinearLayout的分割线如何使用。

很简单的使用,不详细展开了。直接上代码。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:divider="@color/colorAccent"
    android:showDividers="beginning|middle|end"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是你大爷"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是"/>
    <ImageView
        android:background="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

效果图嘛。看这里。

4.1的效果

但是你会发现一个坑爹的情况,就是5.0以上的系统这样设置并没有什么卵用。他没有分割线。

我知道没有图片你们不会相信的。6.0以上也没有,不信你去试试。

android:dividerPadding=”10dp”

这个我就不说了,你们看图也都能够看懂,就是分割线和左右的边距。

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:divider="@color/colorAccent"
android:showDividers="beginning|middle|end"
android:dividerPadding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.selfassu.layoutdemo.MainActivity">
    <TextView
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是你大爷"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是"/>
    <ImageView
        android:background="@mipmap/ic_launcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

LinearLayoutCompat

他就是LinearLayout的兼容类,上面我们不是说了5.0以上没有分割线的效果么?不妨你试试它?会让你有意想不到的惊喜。ps:这玩意和LinearLayout的分割线用法一样。

“什么?你问我这玩意怎么用?”
“查文档去吧”
“什么?你看不懂英文?”
“去google”
“不能翻墙。。。”
“去百度”
你再说不会百度,我建议你别学编程了,因为你不适合。

最后说一句, 学编程的路上困难总是很多,但是只要你认定一个理,坚持下去,我相信困难总比方法多。呸呸呸,方法总比困难多。

时间: 2024-10-09 04:11:05

线性布局的权重究竟是怎么一回事的相关文章

android 59 LinearLayout 线性布局

##常见的布局* LinearLayout 线性布局线性布局往左右拉是拉不动的,> 线性布局的朝向 vertical|horizontal> 线性布局的权重 weight 和 0dip一起使用 <?xml version="1.0" encoding="utf-8"?> <!-- 线性布局控件自上而下整齐的排列 --> <LinearLayout xmlns:android="http://schemas.andr

android之线性布局LinearLayout以及weight权重使用

LinearLayout(线性布局): :layout/activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:lay

第7章(3) LinearLayout(线性布局)

分类:C#.Android.VS2015: 创建日期:2016-02-10 一.简介 LinearLayout将容器内的组件一个挨着一个地横向或纵向依次堆叠起来(不重叠).该布局和WPF的StackPanel控件的功能非常相似,也是通过orientation属性设置排列的方向是纵向(vertical)还是纵向(horizontal). 常用属性有: android:layout_gravity:子元素在容器中的对齐方式.即:往哪一端偏沉(gravity:重力). android:orientat

Android UI之LinearLayout(线性布局)

说明:线性布局是最常用的布局,其包含的所有View会按照线性来排列. 需要注意的就是四个比较常用的xml属性: 1 android:gravity 对应方法:setGravity(int) 说明:这个属性设置布局内组件的对齐方式,支持以下属性值: 属性值 作用 top 将对象放在其容器的顶部,不改变其大小 bottom 将对象放在其容器的底部,不改变其大小 left 将对象放在其容器的左侧,不改变其大小 right 将对象放在其容器的右侧,不改变其大小 left 将对象放在其容器的左侧,不改变其

线性布局

LinearLayout 是一个视图组,用于使所有子视图在单个方向(垂直或水平)保持对齐. 您可以使用 android:orientation 属性指定布局方向. LinearLayout 的所有子视图依次堆叠,因此无论子视图有多宽,垂直列表每行均只有一个子视图,水平列表将只有一行高(最高子视图的高度加上内边距). LinearLayout 遵守子视图之间的"边距"以及每个子视图的"重力"(右对齐.居中对齐.左对齐). 布局权重 权重相等的子视图 要创建一个线性布局

Android——布局(线性布局linearLayout,表格布局TableLayout,帧布局FrameLayout)

线性布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent&q

2.2.1 LinearLayout(线性布局)

本节引言 本节开始讲Android中的布局,Android中有六大布局,分别是: LinearLayout(线性布局),RelativeLayout(相对布局),TableLayout(表格布局) FrameLayout(帧布局),AbsoluteLayout(绝对布局),GridLayout(网格布局) 而今天我们要讲解的就是第一个布局,LinearLayout(线性布局),我们屏幕适配的使用 用的比较多的就是LinearLayout的weight(权重属性),在这一节里,我们会详细地解析 L

LinearLayout线性布局

作用 : 线性布局会将容器中的组件一个一个排列起来, LinearLayout可以控制组件横向或者纵向排列, 通过android:orientation属性控制; 不换行属性 : 线性布局中的组件不会自动换行, 如果组件一个一个排列到尽头之后, 剩下的组件就不会显示出来; 常用属性: (1)基线对齐 xml属性 : android:baselineAligned; 设置方法 : setBaselineAligned(boolean b); 作用 : 如果该属性为false, 就会阻止该布局管理器

LinearLayout (线性布局)的分析

android提供了5中布局,线性布局,相对布局,帧布局.表格布局和绝对布局 线性和相对布局用的是最多的 以下要说的是线性布局 提到线性布局 一定要记住.它里面的全部组件一定不会重叠的, 切不会换行.当组件排列到窗口的边缘后,后面的组件不会显示不来. 线性布局是将放入当中的组件依照水平或者垂直方向来布局的, 线性布局的语法: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"> 属