Android App开发超实用实例 | 约束布局

news2024/12/22 17:23:49

 

 从多个角度介绍约束布局设计中的控件定位。

01、约束布局基础

从 Android Studio 2.3版本起,约束布局是Android Studio布局文件的默认布局。其他布局方式在实现复杂一些的布局设计时存在多种或多个布局嵌套的情况,设备调用这样的布局文件就需要花费更多的时间。约束布局在灵活性和可视化方面比其他布局方式更胜一筹(与号称宇宙第一IDE的Visual Studio的图形化界面设计相比还有差距)。为减少布局嵌套,使用约束布局的属性更接近于相对布局属性。因此,很多资料在讲解约束布局时采用与相对布局类似的方式,不可避免地就要讲解一堆约束布局的定位属性。约束布局与其他布局的最大区别在于支持图形化拖放操作。可以在布局文件的Design视图中采用鼠标拖放操作结合属性栏窗口设置完成约束布局的界面设计,大幅简化布局代码输入和控件间定位关系的人为判断。

【注】

约束布局可以实现图形化拖放设计,但不是真正的所见即所得。Design视图中的效果与实际运行结果还是有所不同的,经常出现的问题是定位属性设置错误或缺项。

选择布局文件main.xml,在Design视图的工具栏中拖放两个Button按钮到Design界面中,如图1所示。

■ 图1 约束布局Design视图

此时由于未加入约束定位,组件树中的控件都会用红色惊叹号标识。运行程序,两个按钮会显示在屏幕左上角,坐标为(0,0)。

选中按钮控件,显示控件句柄,如图2 所示。4个角上的正方形句柄用于调整控件的尺寸,圆形句柄用于设置控件的定位。

 ■ 图2 控件句柄

在“按钮1”左侧圆形句柄上按住鼠标左键并拖向屏幕左侧,此时“按钮1”会自动靠到屏幕左侧,意味着“按钮1”与屏幕左侧对齐。选中“按钮1”再次向右拖动到如图3所示的位置,4个方框圈出数字为132,单位为dp,代表“按钮1”相对父容器(此时为屏幕左边缘)的距离为132dp。也可以在属性栏或布局栏(图中右侧中间的Constraint Widget)中修改数字改变距离值。以上操作对应两个属性: 

■ 图3 “按钮1”相对父容器水平方向定位

注意,一个前缀是“app:”,另一个前缀是“android:”。前者引用app目录下build.gradle文件中androidx.constraintlayout:constraintlayout定义的属性;后者引用系统定义的属性。

同样,选择“按钮1”上方的圆形句柄定位屏幕上边缘距离。重新运行程序,“按钮1”将出现在设定的位置。“按钮2”还是在屏幕左上角。可以采用同样的方式对“按钮2”进行操作,也可以采用相对“按钮1”的位置进行定位。例如,将“按钮2”定位在“按钮1”下方50dp位置,“按钮2”右侧离屏幕右侧100dp。为实现上述定位要求,先选中“按钮2”上方的圆形句柄并拖动到“按钮1”(此时“按钮1”上会出现上、下两个圆形句柄)下方的圆形句柄,调整距离值为50dp。如果进行此操作,鼠标左键释放时指向“按钮1”区域而非圆形句柄,会弹出如图4的上下文菜单,可选择“按钮2”是对齐“按钮1”顶部还是底部。

 ■图4 设定“按钮2”相对“按钮1”的垂直方向定位

选择“按钮2”右侧的圆形句柄并拖动到屏幕右侧,调整距离值为100dp,“按钮2”的定位如图5所示。

■ 图5 “按钮2”的定位

约束布局运行结果如图6所示。

■ 图6约束布局运行结果

设计图与运行图相比,两个按钮的显示位置还是有差异,这是因为设计图并不是按实际设备的屏幕分辨率来设定的,距离真正的所见即所得还有一定的差距。当控件定位属性不全时,组件树会有红色圆形警告标识

,Code视图的控件标签也会标红,同时会多出一个前缀为“tools:”的属性。例如,tools:layout_editor_absoluteX="180dp"指明当前控件在Design视图中的X轴坐标是180dp。此属性只在Design视图中起辅助定位时使用,在运行时还是被忽略的,即运行时控件在X轴坐标还是0(对齐屏幕左侧)。

如果对“按钮1”在水平方向分别将左边缘和右边缘依次定位到屏幕两侧,Android Studio会将“按钮1”在水平方向自动置中,定位标尺直线变为折线,其含义是最终定位还需考虑其他定位属性。Design视图显示水平方向双重定位,如图7所示。运行程序时,“按钮1”也会显示在屏幕水平方向正中央。

■ 图7水平方向双重定位

此时“按钮1”隐含以下属性(此时布局文件中不会显示此属性): 

只要将“按钮1”水平拖动,如图8所示,将多出属性layout_constraintHorizontal_bias,其代表左右定位尺寸(左右圆形句柄到定位基线的距离,定位基线可能是屏幕边缘,也可能是其他控件边缘)的偏离率,0.5代表按钮左右定位长度相等,小于0.5时按钮偏向左边,大于0.5时按钮偏向右边。可以在属性栏中直接修改偏离率,也可以在Inspector(layout_constraintHorizontal_bias属性,如图8标注Constraint Widget的图形部分)中直接拖动带数字的进度条修改偏离率,还可以通过直接拖动“按钮1”的方式或在Code视图中修改偏离率。

■ 图8 layout_constraintHorizontal_bias属性

如果希望“按钮1”无论怎么左右移动,按钮左侧到屏幕左边缘均至少保留50dp的间隙,可先选中“按钮1”,然后在Inspector左侧文本框中输入50,layout_marginStart属性如图9所示。“按钮1”左侧折线连接一段50dp的直线,相应的layout_marginStart属性为50dp,此时偏离率是不计算这50dp直线长度的,即使app:layout_constraintHorizontal_bias属性值等于0,“按钮1”左侧还是会保留50dp的空白,此时拖动“按钮1”到50dp时就无法再向左边移动。

■图9 layout_marginStart属性

选中控件的圆形句柄,按delete键可以删除选中的定位。如果选中的是控件,按delete键会删除整个控件(含控件定位属性)。

Inspector如图10所示。

■ 图10 Inspector

表示wrap_content,Code视图中的属性为android:layout_width="wrap_content"。

表示固定值,给控件指定了一个固定的长度或者宽度值。

表示任意长度或者宽度值。以控件宽度为例,Code视图中控件的宽度属性变为android:layout_width="0"。配合其他定位属性,控件宽度可能为wrap_content(左右圆形句柄只有一个用于定位)、match_parent(左右圆形句柄都用于定位)或任意长度(左右圆形句柄都用于定位,且同时定义了layout_marginStart或layout_marginEnd)。

在“按钮1”上右击,弹出控件快捷菜单,如图11所示。

■ 图11 控件快捷菜单

选择Show Baseline菜单,会在“按钮1”上显示Baseline(即基准线),如图12所示。单击“按钮1”的基准线并拖放到“按钮2”的基准线位置就可实现基准线对齐。基准线对齐主要用在多个高度不同的控件间实现文字对齐(如果按钮中文字显示为多行或两个按钮的字体大小不同,基准线对齐是将第一行文字底部对齐)。

■ 图12  Baseline

选择Clear Constraints of Selection菜单,将删除选中控件的所有约束布局属性。

选择Convert view菜单,弹出转换控件窗口,如图13所示。选择想变更的控件类型(Android中称之为View),可以在保留定位数据的情况下变更控件类型。

■ 图13 转换控件窗口

其他菜单项是常用选项,如复制、粘贴等,还有几个菜单项在设计图上方的工具栏中有相同功能按钮。相关功能可参看后续内容。

Transforms如图14所示。在Transforms中可设置View的X、Y、Z轴的旋转和坐标参照点的偏移。

■ 图14 Transforms

图14中对Z轴旋转了45°,对应属性android:rotation="45"。如果定义在按钮控件内,则对应按钮控件旋转45°。如果定义在ConstraintLayout标签内,则ConstraintLayout标签内的所有控件都会旋转45°。

第7行定义约束布局内所有控件都旋转-45°。此时button1和button2都旋转-45°。

第25行定义button2旋转90°,扣除约束布局旋转的-45°,最终效果是button2旋转45°。

android:rotation属性运行结果如图15所示。其前缀是android,属于android命名空间,所以也可以用在其他布局中,如线性布局。android:rotation是以控件中心且垂直于屏幕为轴心的Z轴旋转。android:rotationX和android:rotationY分别对应控件X方向中心轴和Y方向中心轴旋转。

■ 图15 android:rotation属性运行结果

02、Barrier

在实际布局中可能会遇到Barrier定位,如图16所示。希望“按钮3”布置在“按钮1”和“按钮2”最右侧40dp的位置,即如果“按钮2”比“按钮1”更靠右,则“按钮3”左侧距离“按钮2”右侧40dp;如果“按钮1”比“按钮2”更靠右,则“按钮3”左侧距离“按钮1”右侧40dp。

■ 图16 Barrier定位

为此约束布局引入了Barrier的概念,增加了Barrier标签,其中定义以下两个属性: 

以上两行是在“按钮1”与“按钮2”右侧建立Barrier,Barrier类似一堵墙,两个按钮谁更靠右,这堵墙就以谁为边界。而“按钮3”左侧定位以这个墙为基准。使用图形化界面建立Barrier方法如下:建立“按钮1”与“按钮2”并完成相应定位。选中“按钮1”,单击

按钮,弹出如图17所示的界面,选择Add Vertical Barrier菜单添加一个垂直方向Barrier。

■ 图17 添加垂直方向Barrier

默认添加的Barrier与“按钮1”左侧对齐。修改Barrier属性,如图18所示,在barrier属性栏中修改barrierDirection属性为right(或者是end)、constraint_referenced_ids属性为“button1,button2”(默认只有button1)。如果事先已经明确“按钮1”和“按钮2”共同建立Barrier,也可同时选中“按钮1”和“按钮2”,然后再添加垂直方向的Barrier,constraint_referenced_ids属性自动填写为“button1,button2”。

■ 图18 修改barrier属性

选中“按钮3”,添加左侧定位到任意控件右边缘,使“按钮3”的Declared Attributes属性栏中多出一项layout_constraintStart_toEndOf属性(也可以在All Attributes中查找对应属性),将其改为要对齐的Barrier,将layout_marginStart改为40dp。Android Studio自动生成布局文件,代码如下: 

第35行定义button3左侧对齐到barrier1右侧。

第38~44行定义barrier1,其中第43行定义barrier1阻挡的控件是button1和button2,第42行指明barrier1阻挡方向是右侧。

03、Guideline

之前的控件定位都是基于屏幕(更准确的称呼为控件父容器的约束布局)或者是可见控件,约束布局中引入了一种在运行时看不见的Guideline——定位基准线作为定位补充。添加Guideline如图19所示,分别添加垂直和水平方向的Guideline。

拖动Guideline至所需位置,指定左定位150dp的垂直方向Guideline,如图20所示。

■ 图19 添加Guideline

■ 图20 指定左定位150dp的垂直方向Guideline

单击左侧向上箭头将切换为向下箭头,此时Guideline按Bottom位置定位,再次单击将切换成百分比符号,代表Guideline使用位置百分比设置自身定位(Guideline属性app:layout_constraintGuide_percent="0.33"是将Guideline设置在屏幕长度或宽度的1/3位置),指定百分比的水平方向Guideline,如图21所示。

■ 图21 指定百分比的水平方向Guideline

【注】

目前约束布局版本水平方向的Guideline可通过鼠标单击实现

三种定位方式循环切换,垂直方向的Guideline的切换还有问题。约束布局的功能在不停地升级,或许下一版本会将这个问题解决。

添加控件并将其定位指向Guideline,使用Guideline定位如图22所示。实际运行时Guideline是不可见的。

■ 图22 使用Guideline定位

布局代码如下:

第8~13行定义了一个距离屏幕左边界150dp的垂直方向Guideline。

第15~20行定义了一个距离屏幕上端1/3位置的水平方向Guideline。

第22~29行定义了一个按钮,其顶端和左侧分别定位到两个Guideline。由于Guideline是一条线,因此第28行layout_constraintStart_toStartOf换成layout_constraintStart_toEndOf的效果是一样的。

04、Group

使用约束布局的一个目的是减少布局的嵌套。如果想把多个控件设置为隐藏,就需分别设置各控件的可视化属性。使用Group相当于将各控件进行分组,设置Group属性等效于将Group中各控件设置相同属性。在Design视图中添加Group时需先选择要包含的控件,然后如图23所示选择Add Group菜单项添加的Group对象,新添加Group对象取名为group1。

■ 图22 添加Group

group1在程序运行时是不可见的,要将相应的控件放入group1,最便捷的方式是在组件树中将相应的按钮控件拖放到group1,如图23所示。

■ 图24 将按钮添加到group1

此时group1中包含了button1和button2。Group的关键代码如下: 

其中,第5行定义group1中包含button1和button2。运行程序,可以看到屏幕上显示button1和button2。改变group1的visibility属性为invisible,再次运行程序,屏幕上不显示button1和button2。需要注意的是,group1的属性栏中有两个visibility属性,如图25所示。

■ 图25 visibility属性

上方的visibility属性在Code视图中显示为android:visibility,其设定的值影响相关控件在Android设备上是否显示。下方的visibility属性前有一个

符号,在Code视图中显示为tools:visibility,其设定只影响在Android Studio的Design视图中是否显示,并不影响在Android设备上的运行显示。

05、Circle

Circle方式定位目前还无法使用图形界面操作,可以在Code视图中输入代码。Circle定位示意图如图26所示。以参考定位控件A中心为圆点,以控件B中心到控件A中心为半径,与垂直向上方向的夹角来定位控件B的位置。

■ 图26 Circle定位示意图

第23行定义button2按照Circle方式来定位,定位基准为button1。

第24行定义夹角为45°。

第25行定义button1与button2中心点的距离为150dp。

目前,Circle方定位方式还不完善,除了不支持图形化拖曳设计以外,在Code视图下Button标签也会显示为红色,组件树中button2也会用红色惊叹号标识,提示相关约束属性不完备。

06、Chain

Chain用于指定链式约束。Chain示意图如图27所示。图27中,控件A与控件B相互约束形成一个简单的链式约束。

■ 图27 Chain示意图

链式约束中的第一个控件称为Chain Head。在整个约束链中只要在Chain Head中定义链式约束类型即可。Chain Head示意图如图28所示。

■ 图28 Chain Head示意图

在Head控件中添加layout_constraintHorizontal_chainStyle属性,ChainStyle属性及示意图如图29所示。5种链式约束类型的主要区别是控件间的间隔或控件自身宽度比例。如果Head控件中未设置layout_constraintHorizontal_chainStyle属性,则默认为Spread Chain类型。

■ 图29 ChainStyle属性及示意图

以下是根据官方代码编写的案例,分别实现图350的5种链式约束类型。

5种链式约束类型运行结果如图30所示。

■ 图30 5种链式约束类型运行结果

在Code视图中按钮的文本是小写,但在Design视图和运行结果中都是大写,这是因为从Android 5.0起按钮的属性默认为android:textAllCaps="true"。只要在按钮属性中增加android:textAllCaps="false"即可恢复原有的大小写显示。相应的Java命令为button.setAllCaps(false)。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/5252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(未整理完)十月每日一题打卡

每日打卡 10.1 [重新格式化电话号码 lc1694](1694. 重新格式化电话号码 - 力扣(LeetCode)) 模拟题:特殊情况就是在最后划分完全部三个之后,还剩四个需要变成aa-bb class Solution { public:string reformatNumber(string number…

Redis系列:Redis主从、哨兵、集群介绍

本篇内容包括:Redis 主从架构、Redis 哨兵架构、Redis 集群架构 的介绍等内容~ 文章目录一、Redis 主从架构1、Redis 主从架构2、主从架构原理二、Redis 哨兵模式1、Redis 哨兵模式2、Redis 哨兵模式工作过程三、Redis 集群模式1、Redis 集群模式2、Redi…

【树莓派不吃灰】基础篇⑲ 搭建usb摄像头MJPG-streamer图片流监控,支持远程视频监控访问

目录1. 前言2. 识别摄像头3. MJPG-streamer方案3.1 什么是 MJPG?3.2 MJPG 的优点?3.2 MJPG 的缺点?4. 搭建usb摄像头监控4.1 开启树莓派摄像头开关4.2 查看设备文件4.3 安装必要的库4.4 下载 mjpg-streamer 安装文件4.5 切换到 /mjpg-streame…

基于51单片机的温度甲烷监测报警串口上报proteus仿真原理图PCB

功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前温度和甲烷浓度 2.超过甲烷浓度阈值,蜂鸣器报警 3.按键可更改甲烷浓度阈值上限和启动/暂停检测 4.020%浓度,绿色LED点亮 20%~阈值上限,黄色LED点亮&#xff0…

C#操作modbus

modbus使用范围广泛,广泛应用于各类仪表,PLC等。 modbus的好处是免费,属于应用层协议,底层硬件基于485/以太网。 modbus协议本质还是自定义协议。 modbus调试软件: mthings: modbuspoll: 主站/从站,客…

前端静态页面基本开发思路(一)

有不少刚入门前端的同学经常问我前端布局的问题,总是跟我说在面对学校布置的作业或者想自己搭建博客的时候不知道怎么下手,不知道怎么去写静态的页面,每当我解决了一个又一个同学的问题的时候,又有新的同学来问,故思来…

nginx 配置防盗链(了解)

一 防盗链 1.1 防盗链概念 网站上页面的一些静态资源,不想让本站点的静态资源被他人盗取访问。使用nginx判断请求连接的头部refer中是否含有内容以及合法性来进行处理。 referer表示第二次资源的来源地址 1.2 配置规则 valiad_referers none|blocked|server_na…

Spring--IOC基于XML管理bean

IOC容器 IOC思想 IOC:Inversion of Control 即反转控制 获取资源的传统方式 自己做饭:买菜、洗菜、择菜、改刀、炒菜,全过程参与,费时费力,必须清楚了解资源创建整个过程中的全部细节且熟练掌握。 在应用程序中的组件…

Antd表格性能优化

今天来分享一个实际项目的性能优化的内容。 文章目录一、背景介绍二、性能问题原因及解决方案一、背景介绍 国内React项目大多数人选择配套的UI库的时候都会选择Antd。如果是非常简单的页面用Antd的话其实是完全没问题的,性能感觉不到什么瓶颈,样式也还…

计算机网络

目录 介绍 组成部分 工作方式 功能组成 网络范围分类 传输技术: 总结 标准化工作 RFC文档的作用: 速率,带宽 有容量和速率的区别 带宽 吞吐量 时延,时延带宽积 1.发送时延: 2.传播时延: ​编辑 3.…

Vant组件库 引入 阿里矢量图 添加自己喜欢的 ICON

📃目录跳转一.矢量图下载💨使用CDN方式🎉下载本地(推荐)二.Vant引入Icon🗺️🎃 使用方式🚀 运行效果:一.矢量图下载 💨使用CDN方式 当然你也可以使用官方的C…

【编程题】【Scratch三级】2021.12 分身术

分身术 1. 准备工作 (1)删除小猫角色、添加角色“Monkey”,Money位于舞台的中心; (2)添加背景Light; (3)新建变量“编号”。 2. 功能实现 (1)程序开始时,Monkey说:“我会分身术!变!!!”2秒; (2)每隔2秒克隆出一个位置随机、大小随机、颜色随机的Monke…

python easygui修改窗口位置

EasyGui是一个十分简单的Python图形界面库,支持窗口文本显示、图片显示、按钮、文本框、选项栏、文件选择等等必要的组件且操作十分简单。但也因如此,导致EasyGui甚至不能手动调整窗口位置、按钮位置、名字等,因为EasyGui是基于Tkinter编写的…

VMware三种网络模式详解

VMware三种网络模式 linux重启网络服务命令: service network restart 一、桥接模式 原理:VMware和宿主机,处于同一网段、两者地位平等。(无需虚拟网卡) 1.1、使用方法 虚拟网络编辑器 虚拟机设置-适配器 上面两…

<Linux> 编译器与调试器—gcc/g++/gdb 的使用

< Linux > 编译器与调试器—gcc/g/gdb 的使用 文章目录< Linux > 编译器与调试器—gcc/g/gdb 的使用一、Linux编译器 - gcc/g 使用1. 编译程序的四个过程背景知识预处理编译汇编链接2. 链接方式与函数库2.1 动态链接与静态链接2.2.函数库2.3.动态库与静态库3. gcc/…

干货分享:谷歌主动搜索开发客户的万能公式

大家在用谷歌(Google)开发是不是也有以下常见问题&#xff1a; 关键词不准&#xff0c;搜索到的都是零售商&#xff0c;B2C平台搜索到的客户太大&#xff0c;已经被开发多次&#xff0c;开发信不回复搜索到的客户找不到邮箱搜索到的客户与工厂不匹配&#xff0c;无法合作 其实…

车路协同 智能路侧设备网络安全接入技术要求

1 范围 本文件包含智能路侧设备网络安全接入技术要求&#xff0c;包括智能路侧设备连接要求、接入要求、证书管理要求。 本文件适用于智能路侧设备网络安全接入的设计与开发。 2 规范性引用文件 下列文件中的内容通过文中的规范性引用而构成本文件必不可少的条款。其中&…

Simulink永磁同步电机控制仿真:过调制及电流重构

在一些高功率密度的应用场景中&#xff0c;追求极致的电压利用率&#xff0c;这个时候要用到过调制技术&#xff1b;当svpwm工作在过调制区域时&#xff0c;逆变电桥会在一个基波周期内多次达到100%占空比&#xff0c;且较多时间处于较高的占空比&#xff0c;这个时候下桥臂电流…

数据结构系列学习(七) - 链栈(Chain_Stack)

目录 引言&#xff1a; 学习&#xff1a; 代码实现&#xff1a; 头文件&#xff08;Chain_Stack.h&#xff09;&#xff1a; 设置链栈中的元素范型&#xff1a; 链栈的结构体设计&#xff1a; 所有功能函数的声明&#xff1a; 源文件&#xff08;Chain_Stack.cpp&#…

性能测试场景设计之 阶梯性能场景(负载测试场景)

「负载测试&#xff1a;」 逐步增加并发用户数。看服务器的最大拐点区间在哪里。再缩小拐点区间&#xff0c;找出最大并发用户数。 使用方式&#xff1a; 安装 jpgc插件 添加线程组 每次递增10个并发 This group will start&#xff1a;给定当前负载的并发用户数First, wait …