LinearLayout的andrid:layout_weight属性的使用详解

本文详细解析了Android中layout_weight属性的工作原理,通过实例演示了不同layout_width设置下子视图空间分配的变化,指导开发者如何准确地按照比例分配视图空间。

在开发的过程中,为了布局更好的适配各种各样的屏幕,会经常使用android:layout_weight属性,按比例分配屏幕的空间。在很多资料和书籍中解释说,系统根据layout_weight比例分配占据空间的大小。但是这个解释在实际开发过程中,往往给我们带来许多困惑。 

现在我们来看看具体场景如下:我们需要将三个TextView按照1:2:3的横向的比例显示。于是就有了如下代码: 

[html]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  2.     xmlns:tools="http://schemas.android.com/tools"   
  3.     android:layout_width="match_parent"   
  4.     android:layout_height="match_parent"   
  5.     android:orientation="horizontal" >   
  6.    
  7.     <TextView   
  8.         android:layout_width="wrap_content"   
  9.         android:layout_height="wrap_content"   
  10.         android:layout_weight="1"   
  11.         android:background="#FF4500"   
  12.         android:gravity="center"   
  13.         android:text="第一个" />   
  14.    
  15.     <TextView   
  16.         android:layout_width="wrap_content"   
  17.         android:layout_height="wrap_content"   
  18.         android:layout_weight="2"   
  19.         android:background="#D15FEE"   
  20.         android:gravity="center"   
  21.         android:text="第二个" />   
  22.    
  23.     <TextView   
  24.         android:layout_width="wrap_content"   
  25.         android:layout_height="wrap_content"   
  26.         android:layout_weight="3"   
  27.         android:background="#CAFF70"   
  28.         android:gravity="center"   
  29.         android:text="第三个" />   
  30. </LinearLayout>   
观察结果显示如下(我们分别修改三个TextView的laytou_width属性):  

1.layout_width:wrap_content 


2.layout_width:fill_parent 


3.layout_width:"0dp" 


观察可知,在三种情况下,同样的layout_weight比例1:2:3,0dp的比例正确外,其它两种产生了错误的不同结果,这就让我们非常疑惑。 


在查阅官方文档:Child views can specify a weight value, and then any remaining space in the view group is assigned to children in the proportion of their declared weight。意思是,子视图可以指定一个权重值,然后在这个视图组中的所有剩余空间根据它们声明的权重比例分配 

查阅相关的各方面资料,综合总结,layout_weight比例分配的原则如下 

第一步,根据layout_width/layout_height(根据方向而定)的属性分配视图的空间 

第二步,计算视图组剩余的空间大小,并按照layout_weight比例分配给子视图 

第三步,子视图实际空间=layout_width/layout_height分配空间+layout_weight比例分配空间 

 

根据如上步骤我们分别解释上面三种情况结果的原因 

为了更好的解释,这里我们声明两个常量content_width(内容所需占据的空间大小)和screen_width(屏幕的宽度空间大小)。 

1.layout_width:wrap_content 

第一步,根据layot_width:wrap_content分配三个TextView内容填充的空间,三个TextView的layout_width空间分别为: 

layout_width1=content_width 

layout_width2=content_width 

layout_width3=content_width 

第二步,视图组线性布局剩余的空间大小=screen_width- 3 * content_width;那么三个TextView的layout_weight比例分配空间分别为 

layout_weight1=(screen_width-3*content_width)/6 

layout_weight2=(screen_width-3*content_width)/3 

layout_weight3=(screen_width-3*content_width)/2 

第三步,根据计算公式,子视图实际空间=layout_width/layout_height分配空间+layout_weight比例分配空间 ,三个TextView的空间分别为 

textview1= content_width + (screen_width-3*content_width)/6 

textview2= content_width + (screen_width-3*content_width)/3 

textview3= content_width + (screen_width-3*content_width)/2 

那么textview1:textview2:textview3=(screen_width-2*content_width):2*(screen_width-2*content_width):3*screen_width。显然,该比率是随着content_width和screen_width而变化的,不能满足我们的需求 

2.layout_width:fill_parent 

第一步,三个TextView的layout_width空间分别为 

layout_width1=screen_width 

layout_width2=screen_width 

layout_width3=screen_width 

第二步,三个TextView的layout_weight比例分配空间分别为 

layout_weight1=(screen_width-3*screen_width)/6=-screen_width/3 

layout_weight2=(screen_width-3*screen_width)/3=-2*screen_width/3 

layout_weight3=(screen_width-3*screen_width)/2=-screen_width 

第三步,根据计算公式,子视图实际空间=layout_width/layout_height分配空间+layout_weight比例分配空间 ,三个TextView的空间分别为 

textview1= screen_width - screen_width/3 = 2 * screen_width/3 

textview2= screen_width - 2 * screen_width/3 = screen _width/3 

textview3= screen_width - screen_width = 0 

那么textview1:textview2:textview3=2:1:0,符合我们观察到的现象!但不满足需求。 

3.layout_width:"0dp" 

第一步,三个TextView的layout_width空间分别为 

layout_width1=0dp 

layout_width2=0dp  

layout_width3=0dp 

第二步,三个TextView的layout_weight比例分配空间分别为 

layout_weight1=(screen_width-0dp)/6=screen_width/6 

layout_weight2=(screen_width-0dp)/3=screen_width/3 

layout_weight3=(screen_width-0dp)/2=screen_width/2 

第三步,根据计算公式,子视图实际空间=layout_width/layout_height分配空间+layout_weight比例分配空间 ,三个TextView的空间分别为 

textview1= 0dp+screen_width/6=screen_width/6 

textview2= 0dp+screen_width/3=screen_width/3 

textview3= 0dp+screen_width/2=screen_width/2 

那么textview1:textview2:textview3=1:2:3,符合我们观察到的结果,完全满足我们的需求!!! 


综上的分析和总结,建议在开发的过程当中,如果想根据自己的意愿,按照比例分配子视图占据的空间,将你分配的方向的layout_width或layout_height属性设置为”0dp"。 

<!-- 示例:播放/暂停按钮 --> <ImageButton android:id="@+id/btnPlayPause" android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/ic_play" android:contentDescription="@string/desc_play_button" <!-- 使用字符串资源 --> android:layout_marginHorizontal="16dp" android:background="?attr/selectableItemBackgroundBorderless"/> <!-- 示例:当前歌曲标题 --> <TextView android:id="@+id/currentSongTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/current_song" <!-- 使用字符串资源 --> android:textSize="18sp" android:textStyle="bold" android:gravity="center" android:layout_marginTop="16dp"/> 在哪添加<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" tools:context=".MainActivity"> <!-- 左侧功能区 --> <LinearLayout android:id="@+id/leftPanel" android:layout_width="0dp" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/purple_200" android:padding="16dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintWidth_percent="0.3"> <ImageView android:id="@+id/albumArt" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center_horizontal" android:src="@drawable/music_note" android:contentDescription="@string/album_art" /> <TextView android:id="@+id/currentSongTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/current_song" android:textSize="18sp" android:textStyle="bold" android:gravity="center" android:layout_marginTop="16dp"/> <TextView android:id="@+id/currentArtist" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/artist" android:textSize="16sp" android:gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center" android:layout_marginTop="32dp"> <ImageButton android:id="@+id/btnPrev" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_prev" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/previous"/> <ImageButton android:id="@+id/btnPlayPause" android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/ic_play" android:layout_marginHorizontal="16dp" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/play_pause"/> <ImageButton android:id="@+id/btnNext" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/ic_next" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/next"/> </LinearLayout> <SeekBar android:id="@+id/songProgress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="32dp"/> <TextView android:id="@+id/currentTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0:00" android:layout_gravity="start"/> <TextView android:id="@+id/totalTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0:00" android:layout_gravity="end"/> </LinearLayout> <!-- 右侧歌曲列表 --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/songList" android:layout_width="0dp" android:layout_height="match_parent" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layout_constraintStart_toEndOf="@id/leftPanel" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintWidth_percent="0.7"/> </androidx.constraintlayout.widget.ConstraintLayout>
最新发布
11-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值