Android 布局——LinearLayout、RelativeLayout

官方:https://developer.android.com/develop/ui/views/layout/relative

在本教程中,我们将概述 android 布局。我们还将探索一些可用于组织屏幕内容的特定布局控件,即 Android LinearLayout 和 Android RelativeLayout。

安卓布局

用户界面的基本构建块是从 View 类创建的View对象,它占据屏幕上的一个矩形区域。Views 是 UI 组件(如 TextView、Button、EditText 等)的基类。ViewGroup是 View 的子类。一个或多个 View 可以组合成一个 ViewGroup。ViewGroup 提供了 android 布局,我们可以在其中对视图的外观和顺序进行排序。ViewGroup 的示例是LinearLayout,FrameLayoutRelativeLayout

Android 布局类型

Android 提供以下 ViewGroups 或布局:

  1. LinearLayout: 是一个 ViewGroup,它在一个方向上对齐所有子元素,垂直或水平
  2. RelativeLayout: 是一个 ViewGroup,在相对位置显示子视图
  3. AbsoluteLayout:允许我们指定子视图和小部件的确切位置
  4. TableLayout: 是将其子视图分组为行和列的视图
  5. FrameLayout: 是屏幕上的占位符,用于显示单个视图
  6. ScrollView: 是 FrameLayout 的一种特殊类型,它允许用户滚动浏览比物理显示占用更多空间的视图列表。ScrollView 只能包含一个子视图或 ViewGroup,通常是一个 LinearLayout
  7. ListView: 是一个显示可滚动项目列表的视图组
  8. GridView: 是一个在二维滚动网格中显示项目的 ViewGroup。网格中的项目来自与此视图关联的 ListAdapter

在本教程中,我们将重点介绍两个最常用的 android 布局:

  1. 线性布局
  2. 相对布局

Android 布局属性

  1. android:id:这是唯一标识视图的 ID
  2. android:layout_width:这是布局的宽度
  3. android:layout_height : 这是布局的高度
  4. android:layout_margin:这是视图之外的额外空间。例如,如果你给android:marginLeft=20dp,那么视图将在左起 20dp 之后排列
  5. android:layout_padding:这类似于android:layout_margin,只是它指定了视图内的额外空间
  6. android:layout_gravity:这指定子视图的定位方式
  7. android:layout_weight:这指定布局中应分配多少额外空间给视图
  8. android:layout_x:指定布局的 x 坐标
  9. android:layout_y:指定布局的 y 坐标

android:layout_width= wrap_content告诉视图将自身调整到其内容所需的尺寸。android:layout_width= match_parent告诉视图变得和它的父视图一样大。

查看标识

XML 标记内的 ID 语法为:

  • 字符串开头的 at 符号 (@) 表示 XML 解析器应该解析并扩展 ID 字符串的其余部分,并将其标识为 ID 资源
  • 加号 (+) 表示这是一个新的资源名称,必须创建并添加到我们的资源中

Android 线性布局

Android LinearLayout 沿单行组织元素。我们可以使用 指定该线是垂直的还是水平的android:orientation。默认情况下,方向是水平的。垂直 LinearLayout 每行只有一个子元素(因此它是一列单个元素),而水平 LinearLayout 在屏幕上只有一个元素行。android:layout_weight属性描述了元素的重要性。权重较大的元素会占用更多的屏幕空间。这是使用 LinearLayout 的示例布局 XML:layout_linear.xml

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="@dimen/activity_horizontal_margin">
    <Button
        android:id="@+id/backbutton"
        android:text="Back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:text="Row 2"
        android:layout_width="wrap_content"
        android:textSize="18sp"
        android:layout_margin="10dp"
        android:layout_height="wrap_content" />
    <TextView
        android:text="Row 3"
        android:textSize="18sp"
        android:layout_margin="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:text="Row 4"
        android:textSize="18sp"
        android:layout_margin="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:text="Row 5"
        android:textSize="18sp"
        android:layout_margin="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/next_button"
            android:text="next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="Row 6b"
            android:textSize="18sp"
            android:layout_margin="10dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="Row 6c"
            android:textSize="18sp"
            android:layout_margin="10dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="Row 6d"
            android:textSize="18sp"
            android:layout_margin="10dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</LinearLayout>

在这个布局中,我们有一个父LinearLayout视图,它具有垂直方向并包含按钮、文本视图和嵌套的线性布局(具有水平方向)作为子视图。注意:嵌套布局不必是一种类型。例如,我们可以将 LinearLayout 作为 RelativeLayout 中的子元素之一,反之亦然。

Android 相对布局

Android RelativeLayout 根据元素之间的关系以及与父容器的关系对元素进行布局。这是最复杂的布局之一,我们需要几个属性才能真正获得我们想要的布局。也就是说,使用 RelativeLayout 我们可以将视图定位到toLeftOftoRightOf低于高于其兄弟姐妹。我们还可以相对于其父视图定位视图,例如水平、垂直或两者居中,或与父视图的任何边缘对齐。如果没有在子视图上指定这些属性,则视图默认呈现在左上角位置。RelativeLayout

Android 相对布局属性

以下是RelativeLayout中使用的主要属性。它们分为三个不同的类别:

相对于容器

  • android:layout_alignParentBottom :将元素的底部放置在容器的底部
  • android:layout_alignParentLeft :将元素的左侧放置在容器的左侧
  • android:layout_alignParentRight : 将元素的右侧放置在容器的右侧
  • android:layout_alignParentTop : 将元素放在容器的顶部
  • android:layout_centerHorizo​​ntal :在其父容器中水平居中元素
  • android:layout_centerInParent :在其容器内水平和垂直居中元素
  • android:layout_centerVertical :在其父容器中垂直居中元素

相对于兄弟姐妹

  • android:layout_above : 将元素放在指定元素的上方
  • android:layout_below :将元素放置在指定元素的下方
  • android:layout_toLeftOf :将元素放置在指定元素的左侧
  • android:layout_toRightOf :将元素放置在指定元素的右侧

“ @id /XXXXX”用于通过 id 引用元素。要记住的一件事是,在声明元素之前引用它会产生错误,因此在这种情况下应该使用@+id/。

与其他元素对齐

  • android:layout_alignBaseline : 将新元素的基线与指定元素的基线对齐
  • android:layout_alignBottom : 将新元素的底部与指定元素的底部对齐
  • android:layout_alignLeft :将新元素的左边缘与指定元素的左边缘对齐
  • android:layout_alignRight : 将新元素的右边缘与指定元素的右边缘对齐
  • android:layout_alignTop : 将新元素的顶部与指定元素的顶部对齐

以下 xml 布局使用RelativeLayoutlayout_relative.xml

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="https://schemas.android.com/apk/res/android">
    <Button
        android:id="@+id/backbutton"
        android:text="Back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/firstName"
        android:text="First Name"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/backbutton" />
    <TextView
        android:id="@+id/editFirstName"
        android:text="JournalDev"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/firstName"
        android:layout_below="@id/backbutton"/>
    <TextView
        android:id="@+id/editLastName"
        android:text="Layout Tutorial Example"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/lastName"
        android:layout_toRightOf="@+id/lastName"
        android:layout_toEndOf="@+id/lastName" />
    <TextView
        android:id="@+id/lastName"
        android:text="Last Name"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:layout_below="@+id/firstName"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="40dp"
        android:layout_marginStart="40dp" />

    <Button
        android:id="@+id/next"
        android:text="Next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editLastName"
        android:layout_alignLeft="@+id/editLastName"
        android:layout_alignStart="@+id/editLastName"
        android:layout_marginTop="37dp" />
</RelativeLayout>

如您所见,我们可以根据元素的相对位置重新排列元素。以下 xml 布局表示具有嵌套线性和相对布局的自定义布局。layout_mixed.xml

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="https://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/parent_rl"
        android:text="Parent RelativeLayout"
        android:textSize="18sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout"
        android:layout_below="@id/parent_rl"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true">

        <TextView
            android:text="Nested Horizontal"
            android:textSize="18sp"
            android:layout_margin="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:text="LL"
            android:textSize="18sp"
            android:layout_margin="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />


        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:text="Double Nested"
                android:textSize="18sp"
                android:layout_margin="10dp"
                android:layout_gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <TextView
                android:text="Vertical"
                android:textSize="18sp"
                android:layout_margin="10dp"
                android:layout_gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <TextView
                android:text="LL"
                android:textSize="18sp"
                android:layout_margin="10dp"
                android:layout_gravity="center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </LinearLayout>


    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/linearLayout">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Nested Relative Layout"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

        <Button
            android:id="@+id/back_button_pressed"
            android:text="back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/textView"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="66dp" />

    </RelativeLayout>


</RelativeLayout>

Android 布局项目结构

该项目由三个活动和上面讨论的各自布局组成。

Android 布局代码

应用程序启动到 MainActivity,它layout_linear.xml通过以下代码加载内容:

package com.journaldev.layouts;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {


    Button back,next;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_linear);
        back=(Button)findViewById(R.id.back_button);
        next=(Button)findViewById(R.id.next_button);

        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this,SecondActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        });
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

    }

}

和分别加载SecondActivity和布局如下图:ThirdActivitylayout_relative.xmllayout_mixed.xml

package com.journaldev.layouts;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class SecondActivity extends Activity {
    Button back,next;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_relative);
        back=(Button)findViewById(R.id.backbutton);
        next=(Button)findViewById(R.id.next);

        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(SecondActivity.this,ThirdActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        });
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(SecondActivity.this,MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        });

    }
}
package com.journaldev.layouts;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class ThirdActivity extends Activity {
    Button back;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_mixed);
        back=(Button)findViewById(R.id.back_button_pressed);

        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(ThirdActivity.this,SecondActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
        });

    }
}

三个布局文件的图像输出如下所示:layout_linear.xml

如您所见,Parent LinearLayout 由单个垂直列中的 6 个子元素组成,其中一个是嵌套的 LinearLayout 子视图,其中包含水平方向的 4 个组件。layout_relative.xml 上图中

指向的箭头描述了兄弟姐妹如何相对于彼此以及相对于容器进行定位。layout_mixed.xml

此相对布局由嵌套水平线性布局内的垂直线性布局和子相对布局组成。注意:属于不同布局的组件不是兄弟,因此不能相对于彼此定位。它们的容器布局是同级的,可以相对于彼此定位。如果您想知道蓝线矩形和箭头,那是因为图像来自图形视图中的 xml 布局。当您运行应用程序时,这些蓝线和矩形将不会显示。安卓布局教程到此结束。我们将在接下来的教程中介绍其他android 布局。您可以从下面的链接下载最终的Android 布局项目。

参考:API 文档