【Android -- Layout】概念

224 阅读5分钟

一 布局

1.1 View和ViewGroup

布局(layout)可定义应用中的界面结构(例如 Activity 的界面结构)。布局中的所有元素均使用 View 和 ViewGroup 对象的层次结构进行构建。View 通常绘制用户可查看并进行交互的内容。然而,ViewGroup 是不可见容器,用于定义 View 和其他 ViewGroup 对象的布局结构。

  • 布局的结构层次

  • View 对象通常称为“微件”,可以是众多子类之一,例如 -Button 或 TextView 。
  • ViewGroup 对象通常称为“布局”,可以是提供其他布局结构的众多类型之一,例如LinearLayoutConstraintLayout

1.2 声明布局

  • 在 XML 中声明界面元素,Android 提供对应 View 类及其子类的简明 XML 词汇,如用于微件和布局的词汇。
<?xmlversion="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">
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="HelloWorld!"
    app:layout_constraintBottom_toBottomOf="parent"    
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

  • 在运行时实例化布局元素。您的应用可通过编程创建 View 对象和 ViewGroup 对象(并操纵其属性)。
ConstraintLayoutconstraintLayout=newConstraintLayout(this);
TextViewview=newTextView(this);
view.setText("HelloWorld!");
constraintLayout.addView(view);

1.3 编写XML

  • 利用 Android 的 XML 词汇,按照在 HTML 中创建包含一系列嵌套元素的网页的相同方式快速设计UI 布局及其包含的屏幕元素
  • 每个布局文件都必须只包含一个根元素,并且该元素必须是视图对象或 ViewGroup 对象
  • 定义根元素后,可以子元素的形式添加其他布局对象或控件,从而逐步构建定义布局的视图层次结构
  • 在 XML 中声明布局后,以.xml扩展名将文件保存在Android 项目的res/layout/目录中

1.4 加载 XML 资源

  • 当编译应用时,系统会将每个 XML 布局文件编译成 View 资源。在 Activity.onCreate() 回调内,通过调用 setContentView() ,并以 R.layout.layout_file_name*形式向应用代码传递布局资源的引用 ,加载应用代码中的布局资源。

1.5 属性

  • 每个 View 对象和 ViewGroup 对象均支持自己的各种 XML 属性 。某些属性是 View 对象的特有属性(例如,TextView 支持 textSize 属性),但可扩展此类的任一 View 对象也会继承这些属性。某些属性是所有 View 对象的共有属性,因为它们继承自 View 根类(例如 id 属性)。此外,其他属性被视为“布局参数”,即描述 View 对象特定布局方向的属性,如由该对象的父ViewGroup 对象定义的属性。
<TextView
  android:id="@+id/tv"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"  android:text="HelloWorld!"
  android:textSize="24sp"/>
    
<Button
  android:id="@+id/btn"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"  android:text="按钮"/> 

1.6 ID

任何 View 对象均可拥有与之关联的整型 ID,用于在结构树中对 View 对象进行唯一标识。编译应用后,系统会以整型形式引用此 ID,但在布局 XML 文件中,系统通常会以字符串的形式在 id属性中指定该 ID。这是所有 View 对象共有的 XML 属性

android:id="@+id/tv"
  • 字符串开头处的 @ 符号指示 XML 解析器应解析并展开 ID 字符串的其余部分,并将其标识为 ID 资源。加号 (+) 表示这是一个新的资源名称,必须创建该名称并将其添加到我们的资源(在R.java文件中)内。Android 框架还提供许多其他 ID 资源。引用 Android 资源 ID 时,不需要加号,但必须添加android软件包命名空间
android:id="@android:id/empty"
  • 添加android软件包命名空间后,我们现在将从android.R资源类而非本地资源类引用 ID

  • @+id 和 @id区别

    1. 其实@+id就是在R.java文件里新增一个id名称,如果之前已经存在相同的id名称,那么会覆盖之前的名称。而@id则是直接引用R.java文件的存在的id资源,如果不存在,会编译报错。
    2. ID 字符串名称,在同一布局中必须是唯一的,不能重名,不同布局中可以同名;
    3. 通过ID值创建我们视图对象的实例
    // 设置UI
    <TextView
      android:id="@+id/tv"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"  
      android:text="HelloWorld!"
      android:textSize="24sp"/>
      
    // 引用UI
    TextViewtextView=(TextView)findViewById(R.id.tv);

1.7 布局参数 LayoutParams

  • layout_*** 的布局属性
<TextView
    android:layout_width="100dp"
    android:layout_height="200dp"
    android:layout_marginLeft="10dp"//左边距    
    android:layout_marginTop="10dp"//上边距
    android:text="HelloWorld!"/>
  • 布局参数作用是给我们的视图设定在布局中位置和大小
  • ViewGroup 类会实现一个扩展 ViewGroup.LayoutParams 的嵌套类,里面包含一些设置视图view 的尺寸和位置的属性
TextViewtv=newTextView(this);
LinearLayoutlinearLayout=newLinearLayout(this);LinearLayout.LayoutParamslayoutParams=
(LinearLayout.LayoutParams)tv.getLayoutParams();
layoutParams.leftMargin=30;//左边距
layoutParams.topMargin=30;//上边距
layoutParams.width=100;//宽
layoutParams.height=200;//高
tv.setLayoutParams(layoutParams);
linearLayout.addView(tv);
  • 一般而言,建议不要使用绝对单位(如像素)来指定布局宽度和高度。更好的方法是使用相对测量单位,如与密度无关的像素单位 (dp) 、 wrap_content 或 match_parent ,因为其有助于确保您的应用在各类尺寸的设备屏幕上正确显示。

  • wrap_content 指示您的视图将其大小调整为内容所需的尺寸。

  • match_parent 指示您的视图尽可能采用其父视图组所允许的最大尺寸。

1.8 布局位置

  • 通过 getLeft() 方法和 getTop() 方法来获取视图的坐标位置 ,通过getWidth() getHeight() 获取视图的尺寸,这些方法返回的值是相对于其父视图的位置
  • 位置和尺寸的单位是像素( px )
px 即像素:
  • 1px代表屏幕上一个物理的像素点
  • 给视图设置px单位,不同分辨率下,尺寸不一样

dpi像素密度
  • 每英寸包含的像素数
  • dp (dip) Density independent pixels ,设备无关像素。它与“像素密度”密切相关

假设有一部手机,屏幕的物理尺寸为1.5英寸x2英寸,屏幕分辨率为240x320,则我们可以计算出在这部手机的屏幕上,每英寸包含的像素点的数量为240/1.5=160dpi(横向)或320/2=160dpi(纵向),160dpi就是这部手机的像素密度,像素密度的单位dpi是Dots Per Inch的缩写,即每英寸像素数量.