Android学习之路(3) 布局

线性布局LinearLayout

前几个小节的例程中,XML文件用到了LinearLayout布局,它的学名为线性布局。顾名思义,线性布局 像是用一根线把它的内部视图串起来,故而内部视图之间的排列顺序是固定的,要么从左到右排列,要 么从上到下排列。在XML文件中,LinearLayout通过属性android:orientation区分两种方向,其中从左 到右排列叫作水平方向,属性值为horizontal;从上到下排列叫作垂直方向,属性值为vertical。如果LinearLayout标签不指定具体方向,则系统默认该布局为水平方向排列,也就是默认android:orientation="horizontal".

下面做个实验,让XML文件的根节点挂着两个线性布局,第一个线性布局采取horizontal水平方向,第 二个线性布局采取vertical垂直方向。然后每个线性布局内部各有两个文本视图,通过观察这些文本视图 的排列情况,从而检验线性布局的显示效果。详细的XML文件内容如下所示:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 
    android:layout_width="match_parent"
 
    android:layout_height="match_parent"
 
    android:orientation="vertical">
 
    <LinearLayout
 
        android:layout_width="match_parent"
 
        android:layout_height="wrap_content"
 
        android:orientation="horizontal">
 
        <TextView
 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
 
            android:text="横排第一个"
 
            android:textSize="17sp"
 
            android:textColor="#000000" />
 
        <TextView
 
            android:layout_width="wrap_content"
 
            android:layout_height="wrap_content"
 
            android:text="横排第二个"
 
            android:textSize="17sp"
 
            android:textColor="#000000" />
 
    </LinearLayout>
 
    <LinearLayout
 
        android:layout_width="match_parent"
 
        android:layout_height="wrap_content"
 
        android:orientation="vertical">
 
        <TextView
 
            android:layout_width="wrap_content"
 
            android:layout_height="wrap_content"
 
            android:text="竖排第一个"
 
            android:textSize="17sp"
 
            android:textColor="#000000" />
 
        <TextView
 
            android:layout_width="wrap_content"
 
            android:layout_height="wrap_content"
 
            android:text="竖排第二个"
 
            android:textSize="17sp"
 
            android:textColor="#000000" />
 
    </LinearLayout>
</LinearLayout>

运行测试App,进入如下图所示的演示页面,可见horizontal为横向排列,vertical为纵向排列,说明android:orientation的方向属性确实奏效了。

除了方向之外,线性布局还有一个权重概念,所谓权重,指的是线性布局的下级视图各自拥有多大比例 的宽高。比如一块蛋糕分给两个人吃,可能两人平均分,也可能甲分三分之一,乙分三分之二。两人平 均分的话,先把蛋糕切两半,然后甲分到一半,乙分到另一半,此时甲乙的权重比为1:1。甲分三分之 一、乙分三分之二的话,先把蛋糕平均切成三块,然后甲分到一块,乙分到两块,此时甲乙的权重比为1:2。就线性布局而言,它自身的尺寸相当于一整块蛋糕,它的下级视图们一起来分这个尺寸蛋糕,有的 视图分得多,有的视图分得少。分多分少全凭每个视图分到了多大的权重,这个权重在XML文件中通过 属性android:layout_weight来表达。

把线性布局看作蛋糕的话,分蛋糕的甲乙两人就相当于线性布局的下级视图。假设线性布局平均分为左 右两块,则甲视图和乙视图的权重比为1:1,意味着两个下级视图的layout_weight属性都是1。不过视图 有宽高两个方向,系统怎知layout_weight表示哪个方向的权重呢?所以这里有个规定,一旦设置了layout_weight属性值,便要求layout_width填0dp或者layout_height填0dp。如果layout_width填0dp,则layout_weight表示水平方向的权重,下级视图会从左往右分割线性布局;如果layout_height填0dp,则layout_weight表示垂直方向的权重,下级视图会从上往下分割线性布局。 按照左右均分的话,线性布局设置水平方向horizontal,且甲乙两视图的layout_width都填0dp,layout_weight都填1,此时横排的XML片段示例如下:

复制代码
<LinearLayout
 
        android:layout_width="match_parent"
 
        android:layout_height="wrap_content"
 
        android:orientation="horizontal">
 
    <TextView
 
              android:layout_width="0dp"
 
              android:layout_height="wrap_content"
 
              android:layout_weight="1"
 
              android:text="横排第一个"
 
              android:textSize="17sp"
 
              android:textColor="#000000" />
 
    <TextView
 
              android:layout_width="0dp"
 
              android:layout_height="wrap_content"
 
              android:layout_weight="1"
 
              android:text="横排第二个"
 
              android:textSize="17sp"
 
              android:textColor="#000000" />
</LinearLayout>

按照上下均分的话,线性布局设置垂直方向vertical,且甲乙两视图的layout_height都填0dp,layout_weight都填1,此时竖排的XML片段示例如下:

复制代码
<LinearLayout
 
        android:layout_width="match_parent"
 
        android:layout_height="wrap_content"
 
        android:orientation="vertical">
 
    <TextView
 
              android:layout_width="wrap_content"
 
              android:layout_height="0dp"
 
              android:layout_weight="1"
 
              android:text="竖排第一个"
 
              android:textSize="17sp"
 
              android:textColor="#000000" />
 
    <TextView
 
              android:layout_width="wrap_content"
 
              android:layout_height="0dp"
 
              android:layout_weight="1"
 
              android:text="竖排第二个"
 
              android:textSize="17sp"
 
              android:textColor="#000000" />
</LinearLayout>

把上面两个片段放到新页面的XML文件,其中第一个是横排区域采用红色背景(色值为ff0000),第二 个是竖排区域采用青色背景(色值为00ffff)。重新运行测试App,打开演示界面如下图所示,可见横 排区域平均分为左右两块,竖排区域平均分为上下两块。

相对布局RelativeLayout

线性布局的下级视图是顺序排列着的,另一种相对布局的下级视图位置则由其他视图决定。相对布局名 为RelativeLayout,因为下级视图的位置是相对位置,所以得有具体的参照物才能确定最终位置。如果不设定下级视图的参照物,那么下级视图默认显示在RelativeLayout内部的左上角。 用于确定下级视图位置的参照物分两种,一种是与该视图自身平级的视图;另一种是该视图的上级视图 (也就是它归属的RelativeLayout)。综合两种参照物,相对位置在XML文件中的属性名称说明见下表。

为了更好地理解上述相对属性的含义,接下来使用RelativeLayout及其下级视图进行布局来看看实际效果图。下面是演示相对布局的XML文件例子:

复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 
    android:layout_width="match_parent"
 
    android:layout_height="150dp" >
 
        <TextView
 
        android:id="@+id/tv_center"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_centerInParent="true"
 
        android:background="#ffffff"
 
        android:text="我在中间"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_center_horizontal"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_centerHorizontal="true"
 
        android:background="#eeeeee"
 
        android:text="我在水平中间"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_center_vertical"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_centerVertical="true"
 
        android:background="#eeeeee"
 
        android:text="我在垂直中间"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_parent_left"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_alignParentLeft="true"
 
        android:background="#eeeeee"
 
        android:text="我跟上级左边对齐"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    <TextView
 
        android:id="@+id/tv_parent_right"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_alignParentRight="true"
 
        android:background="#eeeeee"
 
        android:text="我跟上级右边对齐"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    <TextView
 
        android:id="@+id/tv_parent_top"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_alignParentTop="true"
 
        android:background="#eeeeee"
 
        android:text="我跟上级顶部对齐"
 
        android:textSize="11sp"
        android:textColor="#000000" />
 
    <TextView
 
        android:id="@+id/tv_parent_bottom"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_alignParentBottom="true"
 
        android:background="#eeeeee"
 
        android:text="我跟上级底部对齐"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_left_center"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_toLeftOf="@+id/tv_center"
 
        android:layout_alignTop="@+id/tv_center"
 
        android:background="#eeeeee"
 
        android:text="我在中间左边"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_right_center"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_toRightOf="@+id/tv_center"
 
        android:layout_alignBottom="@+id/tv_center"
 
        android:background="#eeeeee"
 
        android:text="我在中间右边"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_above_center"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_above="@+id/tv_center"
 
        android:layout_alignLeft="@+id/tv_center"
 
        android:background="#eeeeee"
 
        android:text="我在中间上面"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
 
    
    <TextView
 
        android:id="@+id/tv_below_center"
 
        android:layout_width="wrap_content"
 
        android:layout_height="wrap_content"
 
        android:layout_below="@+id/tv_center"
 
        android:layout_alignRight="@+id/tv_center"
 
        android:background="#eeeeee"
 
        android:text="我在中间下面"
 
        android:textSize="11sp"
 
        android:textColor="#000000" />
</RelativeLayout>

上述XML文件的布局效果如下图所示,RelativeLayout的下级视图都是文本视图,控件上的文字说明 了所处的相对位置,具体的控件显示方位正如XML属性中描述的那样。

Java程序如下:

复制代码
package com.example.chapter03;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
 
public class RelativeLayoutActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_relative_layout);
    }
}
相关推荐
阿巴斯甜1 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker2 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95273 小时前
Andorid Google 登录接入文档
android
黄林晴4 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab16 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿19 小时前
Android MediaPlayer 笔记
android
Jony_20 小时前
Android 启动优化方案
android
阿巴斯甜20 小时前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇20 小时前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android