一、开发环境的搭建
1.1 开发鸿蒙适合的语言
- Java:适合手机应用的开发
- C/C++:适合硬件的开发
- JavaScript:适合卡片的开发
- 仓颉(即将推出)
Java/JS卡片场景能力差异如下表所示:
场景 | Java卡片 | JS卡片 | 支持的版本 |
---|---|---|---|
实时刷新(类似时钟) | Java使用ComponentProvider做实时刷新代价比较大 | JS可以做到端侧刷新,但是需要定制化组件 | HarmonyOS 2.0及以上 |
开发方式 | Java UI在卡片提供方需要同时对数据和组件进行处理,生成ComponentProvider远端渲染 | JS卡片在使用方加载渲染,提供方只要处理数据、组件和逻辑分离 | HarmonyOS 2.0及以上 |
组件支持 | Text、Image、DirectionalLayout、PositionLayout、DependentLayout | div、list、list-item、swiper、stack、image、text、span、progress、button(定制:chart 、clock、calendar) | HarmonyOS 2.0及以上 |
卡片内动效 | 不支持 | 暂不开放 | HarmonyOS 2.0及以上 |
阴影模糊 | 不支持 | 支持 | HarmonyOS 2.0及以上 |
动态适应布局 | 不支持 | 支持 | HarmonyOS 2.0及以上 |
自定义卡片跳转页面 | 不支持 | 支持 | HarmonyOS 2.0及以上 |
综上所述,JS卡片比Java卡片支持的控件和能力都更丰富:
-
Java卡片:适合作为一个直达入口,没有复杂的页面和事件
-
JS卡片:适合有复杂界面的卡片
1.2 Java开发的准备工作
-
注册华为开发者账号:打开华为开发者联盟官网,使用手机号或邮箱注册账号,并实名认证
-
下载开发工具:DevEco Studio,下载链接DevEco Studio分布式应用开发平台
- JDK:Java语言所需的开发环境。开发工具会自动下载JDK8,目前只支持JDK8
- 工具链:开发工具里需要的一些插件工具
- Toolchains:SDK工具链,HarmonyOS应用开发必备工具集,包括编译、打包、签名、数据库管理等工具的集 合,首次下载SDK时默认下载
- Previewer:Lite Wearable预览器,在开发过程中可以动态预览Lite Wearable应用的界面呈现效果,默认不自 动下载,需手动勾选下载
- 开发工具常见设置:
- 自动提示忽略大小写:File—>settings—>Editor—>General—>Code Completion中,将Match case取消勾选
- 自动导包:File—>settings—>Editor—>General—>Auto Import中,将Add unambiguous imports on the fly和Optimize imports on the fly选中勾选
- 修改自动提示快捷键:File—>settings—>Keymap—>Main meun—>Code—>Code Completion中,将Basic快捷键改为
Alt+/
- DevEco Studio项目结构:
-
MyApplication:项目的项目名
- .gradle:是项目管理工具gradle的信息
- .idea:是开发工具的信息
- build:程序编译运行后会自动生成
- entry:是应用主模块。在一个项目中,有且只有一个,所有的代码都写在这里(重要)
- build:这个文件夹里面有一个R文件,记录每一个资源文件对应的id。里面的内容是自动生成的。 R文件是一个压缩包,里面装的ResourceTable这个类的字节码文件
- libs:第三方jar包存放的位置
- src:主要代码
- main:是我们自己写的主要代码。
- java:里面是我们写的所有代码。
- resources:里面是我们跟界面相关的资源文件。
- config.json:是界面相关所有配置信息,每一个界面都需要在这个里面进行配置。
- main:是我们自己写的主要代码。
- ohosTest:华为的测试工具。
- test:是Junit的测试工具。
- gradle:项目管理工具gradle的配置信息和所需要用到的jar包,在这个里面有一个porperties的配置文件, 可以看到gradle的版本号
- build.gradle:第三方jar包的配置文件,以后在开发中要用到第三方jar包需要在这个里面配置。
- gradlew:是gradle命令工具对应的脚本文件
- local.properties:本地SDK配置信息
-
External Libraries:项目中要导入的第三方jar包
二、鸿蒙入门应用
2.1第一个入门应用-HelloWorld
2.1.1 如何运行应用
-
Tools—>Device Manager中,登录账号
-
选择P40手机,点击右侧青色三角启动
-
点击编译器上方的绿色三角启动项目
2.1.2 页面中的包含关系
-
MainAbility (界面)包含一个或多个MainAbilitySlice(子界面),MainAbilitySlice(子界面)包含要显示的内容
-
MainAbility是项目启动的第一个界面,但是界面里是不直接显示内容的,在界面里面展示的是子界面,我们也称之为切片,或者片段。在子界面里面可以放置内容显示
2.1.3 配置文件config.json
所有的模块,界面等信息,都会在这个文件中进行配置
鸿蒙应用启动之后,先解析config.json文件
config.json文件分为三个部分:
- app :整个项目的配置,包含了厂商信息、版本号等
- bundleName:包名
- vendor:是应用开发厂商的描述,也就是开发公司的名字
- version:包含:name(用户可见的版本号)、code(公司内部人员使用的版本号,用户不可见)
- deviceConfig :表示应用在设备上的配置信息。应用需要获取手机的一些权限,就可以写在deviceConfig里面。如果不需要任何权限就空着
- module:表示整个代码的配置信息
- package:包名
- name:hap包的名字
- mainAbility:表示HAP包的入口ability名称
- deviceType:表示项目可以在哪些设备上运行
- distro:表示HAP包的描述信息
- deliveryWithInstall :当前hap包是否可以支持随应用安装
- moduleName:当前HAP的名称
- moduleType:表示当前HAP的类型
- installationFree:表示该应用是否允许免安装
- abilities:代码中每一个页面的配置信息
2.1.4 程序的启动过程
- 解析config.json文件
- 初始化入口MyApplication
- 获取第一个要启动界面的全类名MainAbility
- 运行代码,并启动第一个界面MainAbility
- 运行界面中的切片MainAbilitySlice
- 加载xml文件Layout_ability_main,展示内容
2.2 第二个入门应用-页面跳转
-
设计思路:
- 在第一个界面添加一个按钮
- 写第二个界面
- 添加跳转关系
-
界面布局:在鸿蒙UI中提供了两种编写布局的方式
- 在XML文件中声明UI布局:比较简单,常用
- 在代码中创建布局
在此,我们用XML布局第一个页面,用代码布局第二个页面
2.2.1 XML文件编写第一个页面
打开src—>main—>resourses—>base—>layout下的ability_main.xml文件,创建一个文本和一个按钮
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<Text
ohos:id="$+id:text_helloworld"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text="$string:mainability_HelloWorld"
ohos:text_size="40vp"
/>
<Button
ohos:id="$+id:but1"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="red"
ohos:text_size="40fp"
ohos:text="点我"
/>
</DirectionalLayout>
2.2.2 Java代码编写第二个页面
在包中新建一个Ability—>Empty Page Ability(Java),命名为SecondAbility,在Slice中会自动生成SecondAbilitySlice文件,SecondAbilitySlice文件代码编写如下:
package com.spring1227.myapplication;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
public class SecondAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// super.setMainRoute(SecondAbilitySlice.class.getName());禁止使用xml文件
//创建一个布局对象
DirectionalLayout dl = new DirectionalLayout(this);
//创建文本对象
Text t = new Text(this);
//设置内容
t.setText("第二个页面");
//设置文字大小
t.setTextSize(55);
//设置文本颜色
t.setTextColor(Color.BLUE);
//把文本对象添加到布局中
dl.addComponent(t);
//把布局添加到子界面中
super.setUIContent(dl);
}
}
2.2.3 编写跳转关系
在MainAbility中编写跳转关系
import ohos.agp.components.Button;
import ohos.agp.components.Component;
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
Button btu;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//找到按钮id
btu = (Button)findComponentById(ResourceTable.Id_but1);
//给按钮添加一个点击事件,点击后执行本类中onClick方法
btu.setClickedListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onClick(Component component) {
//点击后要执行的代码
//跳转到第二个页面
if(component == btu){
//只有点击了这个按钮后才跳转
//跳转到哪(意图)
Intent i = new Intent();
//包含了要跳转的页面信息
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")//要跳转到哪个设备
.withBundleName("com.spring1227.myapplication")//跳转到哪个应用,里面写包名
.withAbilityName("com.spring1227.myapplication.SecondAbility")//要跳转的页面
.build();//将上面的信息打包
//将打包后的operation设置到意图上
i.setOperation(operation);
//跳转页面
startAbility(i);
}
}
}
三、事件
-
事件是可以被识别的操作
-
有了事件,组件就可以和用户交互
-
常见事件有:单击、双击、长按、滑动
3.1 单击事件
接口名:ClickedListener
3.1.1 单击事件的四种写法
3.1.1.1 定义实现类
实例:点击“点我”按钮,按钮文字将变为“第一种单击事件写法”
MainAbilitySlice文件:
package com.spring1227.listenerapplication.slice;
import com.spring1227.listenerapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//第一种单击事件写法:定义实现类
//找到按钮
//完整写法:this表示本类对象(子界面对象) 在子界面中通过id找到相应组件
//this.findComponentById(ResourceTable.Id_but1);才是完整写法,this可以省略
//返回一个组件对象Component(所有组件的父类)
//实际我们需要返回Button类,因此需要再向下转型
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
//给按钮绑定一个单击事件
but1.setClickedListener(new MyListener());
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
class MyListener implements Component.ClickedListener {
//编写类作为接口的实现类
@Override
public void onClick(Component component) {
//component:所有组件的父类
//参数:被点击的组件对象
//访问子类中特有方法:向下转型
Button btu = (Button)component;
btu.setText("第一种单击事件写法");
}
}
ability_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<Button
ohos:id="$+id:but1"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="点我"
ohos:text_size="200"
ohos:background_element="red"
/>
</DirectionalLayout>
3.1.1.2 当前类实现接口
实例:点击“点我”按钮,按钮文字将变为“第二种单击事件写法”,文本框内文字变为“被点击了”
MainAbilitySlice文件:
package com.spring1227.listener2application.slice;
import com.spring1227.listener2application.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
//直接将当前类当做接口的实现类
Text text1 = null;//设为成员变量,使onClick方法得以访问
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//第二种单击事件(常用!)写法:当前类作为实现类
//当点击一个按钮后需要操作其他对象时,用第二种,第一种太麻烦
//找到组件
Button but1 = (Button)findComponentById(ResourceTable.Id_but1);
text1 = (Text)findComponentById(ResourceTable.Id_text1);
//给按钮绑定一个单击事件
//当事件触发时,执行本类中的onClick方法
but1.setClickedListener(this);
text1.setClickedListener(this);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground