直到本书的这一点,所有的用户界面设计任务都是使用 AndroidStudio 布局编辑器工具执行的,无论是文本还是设计模式。编写 XML 资源文件或使用 AndroidStudio 布局编辑器的替代方法是编写 Java 代码来直接创建、配置和操作构成安卓活动用户界面的视图对象。在本章的上下文中,在描述一些关键概念(如视图属性以及布局约束的创建和管理)之前,我们将探讨编写 Java 代码来创建用户界面的一些优缺点。
在下一章中,将创建一个示例项目,用于演示这种安卓用户界面创建方法中涉及的一些典型步骤。
23.1 Java 代码对 XML 布局文件 s
与编写 Java 代码相比,使用 XML 资源文件来设计用户界面有许多关键优势。事实上,谷歌在安卓文档中花了相当多的篇幅来赞美 XML 资源优于 Java 代码的优点。如前一章所述,XML 方法的一个关键优势包括能够使用 AndroidStudio 布局编辑器工具,该工具本身会生成 XML 资源。第二个优点是,一旦创建了应用,只需修改 XML 文件就可以对用户界面屏幕进行更改,从而避免了重新编译应用的必要性。此外,即使手动编写 XML 布局,也可以使用 AndroidStudio 布局编辑器工具的预览功能获得用户界面外观的即时反馈。为了测试 Java 创建的用户界面的外观,开发人员将不可避免地重复编写代码、编译和测试的循环,以完成设计工作。
就布局创建的 Java 编码方法的优势而言,在处理动态用户界面时,Java 相对于 XML 资源文件的最大优势可能会发挥作用。XML 资源文件本质上在定义静态布局时是最有用的,换句话说,在一个活动的一次调用和下一次调用之间,布局不太可能发生显著变化。另一方面,Java 代码非常适合在运行时动态创建用户界面。这在用户界面可能在每次活动执行时因外部因素而出现不同的情况下特别有用。
当需要在活动运行时实时对基于静态 XML 资源的布局进行动态更改时,在 Java 代码中使用用户界面组件的知识也会很有用。
最后,一些开发人员只是更喜欢编写 Java 代码,而不是使用布局工具和 XML,不管后一种方法有什么优势。
23.2 创建视图
如前所述,安卓软件开发工具包包括一个视图类工具箱,旨在满足大多数基本的用户界面设计需求。在 Java 中创建一个视图只是创建这些类的实例,通过一个参数传递对与该视图相关联的活动的引用。
第一个视图(通常是可以添加其他子视图的容器视图)通过调用活动的 setContentView() 方法显示给用户。通过调用对象的 addView() 方法,可以向根视图添加其他视图。
当使用 Java 代码操作包含在 XML 布局资源文件中的视图时,需要获取视图的 ID。同样的规则也适用于用 Java 创建的视图。因此,有必要为任何视图分配一个标识,在后续的 Java 代码中将需要对其进行某些类型的访问。这是通过调用所讨论的视图对象的 setId()方法来实现的。在后面的代码中,视图的标识可以通过对象的 getId()方法获得。
23.3 查看属性
每个视图类都与一系列属性相关联。这些属性设置直接在视图实例上设置,通常定义视图对象的外观或行为。属性的示例包括出现在按钮对象上的文本或约束布局视图的背景颜色。安卓软件开发工具包中的每个视图类都有一组预定义的方法,允许用户设置和获取这些属性值。例如,Button 类有一个 setText()方法,可以从 Java 代码中调用该方法,将按钮上显示的文本设置为特定的字符串值。另一方面,ConstraintLayout 对象的背景色可以通过调用对象的 setBackgroundColor() 方法来设置。
23.4 约束集
属性设置是视图对象的内部设置,决定视图的外观和行为,而约束集用于控制视图相对于其父视图和其他同级视图的外观。每个约束布局实例都与一组约束相关联,这些约束定义了如何定位和约束其子视图。
在 Java 代码中使用约束集的关键是 ConstraintSet 类。此类包含一系列方法,这些方法允许创建、配置约束并将约束应用于约束布局实例等任务。此外,约束布局实例的当前约束可以复制到约束集对象中,并用于将相同的约束应用于其他布局(有或没有修改)。
一个约束集实例就像任何其他 Java 对象一样被创建:
ConstraintSet set = new ConstraintSet();
一旦创建了约束集,就可以在实例上调用方法来执行各种各样的任务。
23.4.1 建立连接
constraint set 类的 connect()方法用于建立视图之间的约束连接。下面的代码配置了一个约束集,其中按钮视图的左侧连接到编辑文本视图的右侧,边距为 70dp:
set.connect(button1.getId(), ConstraintSet.LEFT,
editText1.getId(), ConstraintSet.RIGHT, 70);
23.4.2 将约束应用于布局
一旦配置了约束集,它必须应用于约束布局实例,然后才能生效。通过调用 applyTo()方法来应用约束集,传递对要应用设置的布局对象的引用:
set.applyTo(myLayout);
23.4.3 父约束连接
也可以通过引用约束集,在子视图与其父约束布局之间建立连接。PARENT_ID 常量。在以下示例中,约束集被配置为将按钮视图的上边缘连接到父布局的顶部,边距为 100dp:
set.connect(button1.getId(), ConstraintSet.TOP,
ConstraintSet.PARENT_ID, ConstraintSet.TOP, 100);
23.4.4 尺寸约束
有许多方法可用于控制视图的大小调整行为。例如,下面的代码将 Button 视图的水平大小设置为 wrap_content,将 ImageView 实例的垂直大小设置为最大值 250dp:
set.constrainWidth(button1.getId(), ConstraintSet.WRAP_CONTENT);
set.constrainMaxHeight(imageView1.getId(), 250);
23.4.5 约束偏差
如标题为“AndroidStudio 中使用约束布局的指南”一章所述,当一个视图有相反的约束时,它沿着约束的轴居中(即水平或垂直)。这种对中可以通过沿特定的约束轴施加偏置来调整。当使用 AndroidStudio 布局编辑器时,这是使用属性工具窗口中的控件来实现的。但是,当使用约束集时,可以使用 sethorizontalibias()和 setVerticalBias()方法添加偏差,将视图标识和偏差作为 0 到 1 之间的浮点值进行引用。
例如,以下代码在应用 25%的水平偏移之前,将按钮的左侧和右侧约束到父布局的相应侧:
set.connect(button1.getId(), ConstraintSet.LEFT,
ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0);
set.connect(button1.getId(), ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0);
set.setHorizontalBias(button1.getId(), 0.25f);
23.4.6 对齐约束
也可以使用约束集应用对齐。AndroidStudio 布局编辑器提供的全套对齐选项也可以通过中心垂直()和中心水平()方法使用约束集进行配置,这两种方法都采用各种参数,具体取决于正在配置的对齐方式。此外,center()方法可用于使视图在两个其他视图之间居中。
在下面的代码中,按钮 2 的位置与按钮 1 水平对齐:
set.centerHorizontally(button2.getId(), button1.getId());
23.4.7 复制和应用约束集
可以使用克隆()方法将约束布局实例的当前约束集复制到约束集对象中。例如,下面一行代码将名为 myLayout 的 ConstraintLayout 实例中的约束设置复制到约束集对象中:
set.clone(myLayout);
复制后,约束集可以直接应用于另一个布局,或者在应用于第二个布局之前进行修改,如下例所示:
ConstraintSet set = new ConstraintSet();
set.clone(myLayout);
set.constrainWidth(button1.getId(), ConstraintSet.WRAP_CONTENT);
set.applyTo(mySecondLayout);
23.4.8 约束布局链
也可以使用创建水平链()和创建垂直链()方法在约束集中创建垂直链和水平链。使用这些方法的语法如下:
createHorizontalChain(int leftId, int leftSide, int rightId,
int rightSide, int[] chainIds, float[] weights, int style);
基于上面的语法,下面的示例创建了一个以 button1 开始,以 button4 结束的水平扩展链。在这两个视图之间是按钮 2 和按钮 3,两者的权重都设置为零:
int[] chainViews = {button2.getId(), button3.getId()};
float[] chainWeights = {0, 0};
set.createHorizontalChain(button1.getId(), ConstraintSet.LEFT,
button4.getId(), ConstraintSet.RIGHT,
chainViews, chainWeights,
ConstraintSet.CHAIN_SPREAD);
通过将要移除的视图的标识传递给 removefrohorizontalchain()或 removefroverticalchain()方法,可以从链中移除视图。可以使用添加到 HorizontalChain()或添加到 VerticalChain()方法将视图添加到现有链中。在这两种情况下,方法都将视图的标识作为参数,在这些视图之间插入新视图,如下所示:
set.addToHorizontalChain(newViewId, leftViewId, rightViewId);
23.4.9 指南
使用 create()方法将指导添加到约束集,然后使用设置指导线开始()、设置指导线结束()或设置指导线百分比()方法定位。在下面的代码中,创建了一条垂直指导线,并将其放置在父布局宽度的 50%处。然后,按钮视图的左侧连接到无边距的指南:
set.create(R.id.myGuideline, ConstraintSet.VERTICAL_GUIDELINE);
set.setGuidelinePercent(R.id.myGuideline, 0.5f);
set.connect(button.getId(), ConstraintSet.LEFT,
R.id.myGuideline, ConstraintSet.RIGHT, 0);
set.applyTo(layout);
23.4.10 移除约束
可以使用 clear()方法从约束集中的视图中移除约束,将视图标识和要移除约束的锚点作为参数传递:
set.clear(button.getId(), ConstraintSet.LEFT);
同样,通过在 clear()方法调用中仅引用视图,可以在一个步骤中删除视图上的所有约束:
set.clear(button.getId());
23.4.11 缩放
可以使用 ConstraintSet setScaleX()和 setScaleY()方法来调整布局中视图的比例,这两种方法将执行操作的视图以及指示比例的浮点值作为参数。在下面的代码中,按钮对象被缩放到其原始宽度的两倍和高度的一半:
set.setScaleX(myButton.getId(), 2f);
set.setScaleY(myButton.getId(), 0.5f);
23.4.12 旋转
可以分别使用 设置旋转 X()和设置旋转 Y()方法在 X 轴或 Y 轴上旋转视图,这两种方法都必须传递要旋转的视图的 ID 和表示要执行的旋转程度的浮点值。可以通过调用 setTransformPivot()、setTransformPivotX()和 setTransformPivotY()方法来定义要进行旋转的枢轴点。以下代码使用位于点 500、500 的枢轴点将按钮视图在 Y 轴上旋转 30 度:
set.setTransformPivot(button.getId(), 500, 500);
set.setRotationY(button.getId(), 30);
set.applyTo(layout);
已经介绍了 Java 代码中的约束集和用户界面创建的理论,下一章将通过创建一个示例应用来实现这个理论。有关约束集类的更多详细信息,请参考以下网址的参考指南:
https://developer . Android . com/reference/androidx/constraint layout/widget/constraint set
23.5 总结
作为编写 XML 布局资源文件或使用 AndroidStudio 布局编辑器工具的替代方法,安卓用户界面也可以用 Java 代码动态创建。
在 Java 代码中创建布局包括创建视图类的实例,并在这些对象上设置属性以定义所需的外观和行为。
视图相对于其约束布局父视图和任何同级视图的位置和大小是通过使用约束集来定义的。约束集由 constraint set 类的一个实例表示,一旦创建,就可以使用各种方法调用进行配置,以执行诸如建立约束连接、控制视图大小调整行为和创建链等任务。
本章介绍了 ConstraintSet 类的基础知识,下一章将通过一个教程来介绍这些特性的实际应用。