HarmonyOS应用开发 | 您所在的位置:网站首页 › 一个页面实现登录注册 › HarmonyOS应用开发 |
本篇文章我来手把手教大家做一个HarmonyOS 应用的登录页面,逐步讲解,非常细致,百分百能学会,并提供全部源码。页面使用 DevEco Studio 的低代码开发。 通过本文的实践经验,我想告诉大家, HarmonyOS 应用开发其实并不难,只要了解具体的开发流程和开发思想,大家都可以很快上手。祝愿大家都可以赶上时代浪潮,让青春随鸿蒙千帆飘扬! 下面这张图是我们的目标实现图,具体实现流程将由我一步一步讲解: 一、项目初始化 1、创建低代码项目下载安装 DevEco Studio,新建一个支持 Super Visual 低代码模式的项目。 具体过程可以参考我上一篇文章:HarmonyOS应用开发-搭建开发环境 2、低代码项目结构解读初始项目目录如下: ├──entry/src/main/ets // 代码区 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 │ └──pages │ └──Index.ets // 首页的逻辑描述文件 ├──entry/src/main/resources // 资源文件 └──entry/src/main/supervisual └──pages └──Index.visual // 首页的数据模型其中.ets文件就是我们正常编写界面逻辑的文件,语言为ArcTS; .visual为低代码项目特有的文件,由系统根据我们对界面的可视化设计自动更新,用写字板打开能看到是存储界面设计的Json文本; 二、添加静态文件 1、新增图片文件ets 文件下创建 common\images\icon 文件夹,icon内添加我们需要添加的图片文件,本教程我们用到了3个“其他登录方式”的图标。 添加的图标图片如下: 增加完三个图标后,我们的项目结构更新如下: ├──entry/src/main/ets // 代码区 │ ├──common │ │ └──images │ │ └──icon // 图标图片 │ │ ├──csdn.png // 图标A │ │ ├──huawei.png // 图标B │ │ └──openatom.png // 图标C │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 │ └──pages │ └──Index.ets // 首页的逻辑描述文件 ├──entry/src/main/resources // 资源文件 └──entry/src/main/supervisual └──pages └──Index.visual // 首页的数据模型 2、新增常量类这一步可选,一般意义上,我们会根据系统业务需要把一些固定的参数写到一个记录常量的 ArcTS 文件里,比如命名为 Const.ts,本次我们把页面需要的常量写到了页面自带的 index.ets文件里,所以没有建立常量类,特此说明。 如果需要添加,我们可以把常量类 Const.ts 放在和 images 文件夹平级的位置,添加 Const.ts 之后的项目结构如下: ├──entry/src/main/ets // 代码区 │ ├──common │ │ ├──Const.ts // 常量类 │ │ └──images │ │ └──icon // 图标图片 │ │ ├──csdn.png // 图标A │ │ ├──huawei.png // 图标B │ │ └──openatom.png // 图标C │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 │ └──pages │ └──Index.ets // 首页的逻辑描述文件 ├──entry/src/main/resources // 资源文件 └──entry/src/main/supervisual └──pages └──Index.visual // 首页的数据模型 三、编写登录页界面 1、低代码设计界面布局 ① 放置容器组件初始话的页面如图,Root 根结构下包含一个 Column 的容器,容器里有一个 "Hello World" 的 Text 文本控件。 我们直接复用这个 Column 容器,删除 Text 控件(左侧组件树或右侧可视化屏幕里选中控件然后按Backspace键就可以删除)。 ② 放置图标图片如图,我们需要放置一个水平居中的应用图标: 思路:下面我们来实现登录页面的图标,我们需要创建一个行容器(Row),然后拖一个图片组件(Imgae)进去,并使图片居中。 操作:在列容器(Cloumn)里拖一个行容器(Row)过去,宽度(width)设置为 100%,高度(height)设置为 100vp,设置水平居中、垂直居中,位置为绝对定位(Position),距离页面上方 95vp 距离。 然后我们拖入图片组件(Imgae),设置图片宽高均为 100vp(和Row的高相等)。 图片的Src(图片存储路径)设置为app自带的默认图标,至此我们的登录页应用图标就显示出来了。 ③ 放置描述文字接下来,我们需要放置描述性文本,如图: 思路:这里用到的是文本组件(Text),我们需要填写文字内容、定义字体大小和组件的位置。 操作:拖两个文本组件(Text)到行容器(Row)下面。 设置内容(Content)为 "用户登录",字体大小(FontSize)为 26fp,字体对齐(TextAlign)为居中(Center),文字组件框体大小(Size)为宽度 100%,高度 50vp,位置为绝对定位(Position),距离页面顶部 200vp。效果图如下: 同理,我们制作 "登录账号以使用更多服务" 文本框。 我们设置文本框内容(Content)为 "登录账号以使用更多服务",字体大小(FontSize)为 14fp,字体对齐(TextAlign)为居中(Center),文字组件框体大小(Size)为宽度 100%,高度 30vp,位置为绝对定位(Position),距离页面顶部 250vp,字体颜色(FontColor)为 #8c8c8c(灰色)。效果图如下: ④ 放置账号密码输入框接下来,我们要制作账号密码的输入部分,这里用到的是文本输入组件(TextInput)。 目标实现效果如下: 思路:我们需要两个文本输入组件(TextInput)用来实现账号、密码的录入,下方 "短信验证码登录" 和 "忘记密码",我们使用普通文本组件(Text)实现,让两个普通文本组件(Text)并列在一行,然后一个左对齐,一个右对齐。 操作流程: 首先,我们处理账号和密码输入两个文本输入框。 拖两个文本输入组件(TextInput)在我们之前拖的组件下面。 设置文本输入组件一(text-input1): 设置文本占位符(Placeholder)为 "邮箱/手机号/用户名",类型(Type)为 Normal; 组件框体大小(Size)为宽度(Width)为 100%,高度(Height)为 50vp; 背景颜色(BackgroundColor)为白色(#ffffff); 边框(Border)只要底边框,底边框宽度(BorderBottomWidth)为 1vp,边框颜色(BorderColor)为深灰色(#4a4a4a); 位置为绝对定位(Position),距离页面顶部 328vp。 效果图如下: 设置文本输入组件二(text-input2): 设置文本占位符(Placeholder)为 "邮箱/手机号/用户名",类型(Type)为 Password; 组件框体大小(Size)为宽度(Width)为 100%,高度(Height)为 50vp; 背景颜色(BackgroundColor)为白色(#ffffff); 边框(Border)只要底边框,底边框宽度(BorderBottomWidth)为 1vp,边框颜色(BorderColor)为深灰色(#4a4a4a); 位置为绝对定位(Position),距离页面顶部 380vp。 效果图如下: 下一步,我们来制作两个输入框下面的 "短信验证码登录" 和 "忘记密码"。 拖一个行容器(Row)到文本输入框组件下面,设置行容器(Row)的属性。 设置组件居中; 设置组件的尺寸(Size),宽度(Width)为 94%,高度(Height)为 30vp; 设置组件位置为绝对定位(Position),距离页面顶部 430vp,距离左侧为 3%; 接着,我们往容器里拖两个文本组件(Text)。 设置组件属性如下: 组件一(text5)内容为 "短信验证码登录",字体居左,字体大小为 14fp; 定义尺寸(Size),宽度(Width)为 50%,高度(Height)为 30vp; 组件位置为绝对定位(Position),距离左侧为 0%; 组件二(text6)内容为 "忘记密码",字体居右,字体大小为 14fp; 定义尺寸(Size),宽度(Width)为 50%,高度(Height)为 30vp; 组件位置为绝对定位(Position),距离左侧为 50%; ⑤ 放置登录按钮这一步是最简单的,制作登录按钮部分,只需要一个按钮组件(Button)和一个文本组件(Text)。 目标实现效果如下: 思路:我们拖一个按钮组件(Button),再在按钮下方拖一个文本组件(Text)即可。 操作流程: 首先,我们拖一个按钮组件。 定义组件的属性: 设置组件宽度(Width)为 90%,高度(Height)为 40vp; 内容为"登录",字体默认居中,字体大小为 20fp; 组件位置为绝对定位(Position),距离左侧为 5%,距离顶部 530vp; 下方再拖一个文本组件(Text),设置组件属性: 文本组件内容为 "注册账号",字体居中,字体大小为 14fp; 定义尺寸(Size),宽度(Width)为 100%,高度(Height)为 30vp; 组件位置为绝对定位(Position),距离顶部为 570vp; ⑥ 放置Grid网格控件最后,我们来制作其他登录方式的选择部分,这里用到的是网格组件(Grid)、网格内单个元素(GridItem)、其他常见组件(图片、文字、行/列等)。 目标实现效果如下: 思路:我们需要一个网格组件(Grid),组件内包含若干个子元素,这个用Grid内对象组件(GridItem)可以实现,这样我们就可以根据我们后端传值的数目来动态显示登录方式,而不是把三种登录方式固定写死。每个Grid内子元素(GridItem)里放置一个行容器(Row),行容器(Row)里上方放一个图片组件(Image),下方放一个文本组件(Text)。 操作流程: 首先,我们拖一个网格组件(Grid),设置组件属性: 组件宽度(width)设置为 100%,高度(height)设置为 10%; 内容居中,绝对定位,距离顶部 90%; 往网格组件(Guid)里拖一个GuidItem组件,这是一个动态显示的子元素组件,会根据我们提供的参数动态进行内容显示,由于我们在设计上固定为行内显示3个,所以宽度就直接定为33.3%了。 设置GridItem组件属性: 组件宽度(width)设置为 33.3%,高度(height)设置为 100%(因为是相对于Grid); 往GridItem里拖入一个行容器(Row),设置组件属性: 高度和宽度均为 100%; 然后再往行容器(Row)里拖一个图片组件(Image)和一个文本组件(Text); 设置组件属性: 图片(Image)组件: 图片路径(Src),我们使用编译器自带的 Logo; 对象适应方式(ObjectFit) 为包含(Contain); 组件宽度(width)设置为 70%,高度(height)设置为 56%; 距离上边距(MarginTop) 10%; 绝对定位,距离左侧 15%; 文字(Text)组件: 文字内容(Content),我们先随便填个 "测试"; 文本居中; 组件宽度(width)设置为 100%,高度(height)设置为 24%; 绝对定位,距离顶部 60%(60%~70%均可); 做到这里,我们的ArcUI的设计就完成了,是不是觉得和下面三个图标的目标效果还有点差距,别急,我们接下来就来实现GridItem数据的动态渲染。 2、实现数据动态渲染下一步,我们来实现数据的动态渲染,在这个登录页面,我们需要对GridItem组件及其内部组件的属性进行动态赋值。 ① 创建数据源我们先创建数据源,打开页面对应的 ArcTS 文件(比如你现在编辑的可视化低代码界面是Index.visual,那么对应的 ArcTS 文件就是 Index.ets) 默认的页面 .ets 文件内容如下: @Entry @Component struct Index { @State message: string = 'Hello World' build() { } }我们在这里创建 FunctionType 对象,用来装配我们需要显示的图片路径和文字内容。 然后再定义状态变量 avenues,数组类型,用来包含我们装配图片路径和文字内容的 FunctionType 对象。 更新后的代码如下: class FunctionType { name: string; icon: string; } @Entry @Component struct Index { @State avenues: Array = [ { name: 'HuaWei', icon: "common/images/icon/huawei.png" }, { name: 'CSDN', icon: "common/images/icon/csdn.png" }, { name: 'OpenAtom', icon: "common/images/icon/openatom.png" } ] build() { } } ② 更新动态渲染组件属性回到我们低代码页面 Index.visual,修改网格子元素组件(GridItem)的Render里的ForEach属性为this.avenues,其他默认; 然后我们再分别选中GridItem里的图片组件和文本组件,对其勾选动态值。 图片组件(Image)的图片路径(Src)选择 item1.icon; 文本组件(Text)的内容(Content)选择 item1.name; 然后我们到预览器(Preview)的窗口里就可以看到已经完成的效果了。 至此,我们的低代码开发部分已全部完成! 3、低代码页面转为ArcTs文件这步是可选步骤,根据实际需要决定是否要转,低代码和 ArcTs 在开发页面上各有优势。低代码开发迅速、改动简单,ArcTS 则更方便自定义一些事件,拥有更好的扩展性。一般对于涉及交互业务的页面,页面的功能会相对比较复杂,推荐使用 ArcTS,如果是登录页这种简单业务逻辑页面,可以保留低代码版本,不必转化为 ArcTS 版本。 如果有需要将 .visual 页面转换为 .ets 文件,我们可以点击右上角的转换按钮。 此操作能够将低代码界面转换为 ArcTS 的代码。注意:转换完之后原有的 .visual 文件会被删除!这个过程不可逆! 目前编译器点击转换按钮后会有 ArcTS 的预览代码,需要点击 Convert 来确认此次操作,本次界面转换结果的预览代码如下: Index.ets class FunctionType { name: string; icon: string; } @Entry @Component struct Index { @State avenues: Array = [ { name: 'HuaWei', icon: "common/images/icon/huawei.png" }, { name: 'CSDN', icon: "common/images/icon/csdn.png" }, { name: 'OpenAtom', icon: "common/images/icon/openatom.png" } ] build() { Column() { Column() { Row() { Image($r('app.media.icon')) .width("100vp") .height("100vp") .align(Alignment.Center) .offset({ x: "0%", y: "0vp" }) .backgroundImageSize(ImageSize.Auto) } .width("100%") .height("100vp") .position({ x: "0", y: "95vp" }) .displayPriority(0) .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.Center) Text("用户登录") .width("100%") .height("50vp") .position({ x: "0vp", y: "200vp" }) .borderRadius({ topRight: "0vp" }) .textAlign(TextAlign.Center) .textOverflow({ overflow: TextOverflow.Clip }) .fontSize("26fp") .fontWeight(FontWeight.Medium) .fontFamily("sans-serif") Text("登录帐号以使用更多服务") .width("100%") .height("30vp") .position({ x: "0vp", y: "250vp" }) .fontColor("#8c8c8c") .textAlign(TextAlign.Center) .fontSize("14fp") TextInput({ placeholder: "邮箱/手机号/用户名" }) .width("100%") .height("50vp") .position({ x: "0vp", y: "328vp" }) .borderWidth({ bottom: "1vp" }) .borderColor({ bottom: "#4a4a4a" }) .backgroundColor("#ffffff") .margin({ bottom: "0vp" }) .padding({ top: "0vp" }) .type(InputType.Normal) TextInput({ placeholder: "密码" }) .width("100%") .height("50vp") .position({ x: "0vp", y: "380vp" }) .borderWidth({ bottom: "1vp" }) .borderColor({ bottom: "#4a4a4a" }) .backgroundColor("#ffffff") .type(InputType.Password) Row() { Text("忘记密码") .width("50%") .height("30vp") .position({ x: "50%", y: "0px" }) .textAlign(TextAlign.End) .fontSize("14fp") Text("短信验证码登录") .width("50%") .height("30vp") .position({ x: "0%", y: "0vp" }) .textAlign(TextAlign.Start) .fontSize("14fp") } .width("94%") .height("30vp") .position({ x: "3%", y: "430vp" }) Grid() { if (true) { ForEach(this.avenues, (item1: any, idx1: number) => { GridItem() { Row() { if (true) { Text(`${item1.name}`) .width("100%") .height("24%") .position({ x: "0%", y: "60%" }) .textAlign(TextAlign.Center) .fontSize("14fp") } Image($r('app.media.icon')) .width("70%") .height("56%") .position({ x: "15%", y: "0vp" }) .margin({ top: "10%", bottom: "0vp", left: "0%", right: "0%" }) .objectFit(ImageFit.Contain) } .width("100%") .height("100%") } .width("33.3%") .height("100%") .align(Alignment.Start) .offset({ x: "0vp", y: "0" })}) } } .width("100%") .height("10%") .align(Alignment.Center) .position({ x: "0vp", y: "90%" }) .backgroundImageSize(ImageSize.Auto) .opacity(0.99) .margin({ top: "0vp", bottom: "0vp", left: "0vp", right: "0vp" }) .padding({ top: "0vp", bottom: "0vp" }) .scrollBar(BarState.Off) Button("登录") .width("90%") .height("40vp") .position({ x: "5%", y: "530vp" }) .fontSize("20fp") Text("注册账号") .width("100%") .height("30vp") .position({ x: "0vp", y: "570vp" }) .textAlign(TextAlign.Center) .fontSize("14fp") Text("其他方式登录") .width("100%") .height("4%") .align(Alignment.Center) .position({ x: "0vp", y: "85%" }) .textAlign(TextAlign.Center) .fontSize("14fp") } .width("100%") .height("100%") .position({ x: "0vp", y: "0vp" }) .borderWidth({ bottom: "1vp" }) .borderColor({ bottom: "#4a4a4a" }) .justifyContent(FlexAlign.Center) } .width("100%") .height("100%") } } 四、测试应用 1、启动仿真器右上角选择设备,点击进入设备管理器,如果没有对应的仿真设备,需要下载安装,如果已经有,选择 Huawei_Phone 作为调试的仿真设备,点击启动。 2、界面测试点击右上角启动键,启动项目。 有的时候会因为页面删除但是页面配置没清除完全导致运行失败,这个需要到项目启动类的配置文件里手动删除多出来的页面,启动类配置文件的路径是 DevEco-Studio\Test-Project\Harmony\entry\src\main\resources\base\profile\main_pages.json; 程序启动成功,运行效果如图: |
CopyRight 2018-2019 实验室设备网 版权所有 |