Android布局 – LinearLayout(线性布局),RelativeLayout(相对布局)

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

Android布局

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

Android布局类型

Android提供了以下ViewGroup或布局:

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

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

  1. LinearLayout
  2. RelativeLayout

安卓布局属性

  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告诉视图变得与其父视图一样大。

视图标识

ID的XML标签内的语法为:

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

Android LinearLayout

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

Android RelativeLayout

Android RelativeLayout 根据元素彼此之间和与父容器的关系进行布局。这是最复杂的布局之一,我们需要多个属性才能实现我们想要的布局。也就是说,使用RelativeLayout,我们可以将视图定位为其兄弟视图的左侧右侧下方上方。我们还可以将视图相对于其父视图定位,如水平居中垂直居中或两者兼而有之,或与父RelativeLayout的任何边缘对齐。如果在子视图上未指定这些属性中的任何一个,则默认将该视图呈现在左上位置。

Android RelativeLayout 属性

以下是跨RelativeLayout的三个不同类别中使用的主要属性:

相对于容器

  • android:layout_alignParentBottom:将元素的底部放置在容器的底部
  • android:layout_alignParentLeft:将元素的左侧放置在容器的左侧
  • android:layout_alignParentRight:将元素的右侧放置在容器的右侧
  • android:layout_alignParentTop:将元素放置在容器顶部
  • android:layout_centerHorizontal:在其父容器中水平居中元素
  • 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();
            }
        });

    }

}

SecondActivityThirdActivity 分别加载 layout_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 如您所见,父 LinearLayout 包含了 6 个子元素,位于单个垂直列中,其中一个是一个包含 4 个组件的水平方向的嵌套 LinearLayout 子视图。layout_relative.xml 上述图像中的箭头指示了兄弟元素相对于彼此和相对于容器的位置。layout_mixed.xml 此相对布局包含一个垂直 LinearLayout 和一个嵌套的水平 LinearLayout,以及一个子 RelativeLayout。注意:属于不同布局的组件不是兄弟元素,因此不能相对于彼此定位。它们的容器布局是兄弟元素,可以相对于彼此定位。如果您想知道蓝色线条和箭头的含义,那是因为这些图像来自 XML 布局的图形视图。当您运行应用时,这些蓝色线条和矩形将不会显示。这就结束了 Android 布局教程。我们将在下一个教程中介绍其他Android 布局。您可以从下面的链接下载最终的Android 布局项目

下载 Android LinearLayout RelativeLayout 示例项目

参考: API 文档

Source:
https://www.digitalocean.com/community/tutorials/android-layout-linearlayout-relativelayout