一、开发环境的搭建

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开发的准备工作

  1. 注册华为开发者账号:打开华为开发者联盟官网,使用手机号或邮箱注册账号,并实名认证

  2. 下载开发工具:DevEco Studio,下载链接DevEco Studio分布式应用开发平台

  • JDK:Java语言所需的开发环境。开发工具会自动下载JDK8,目前只支持JDK8
  • 工具链:开发工具里需要的一些插件工具
    • Toolchains:SDK工具链,HarmonyOS应用开发必备工具集,包括编译、打包、签名、数据库管理等工具的集 合,首次下载SDK时默认下载
    • Previewer:Lite Wearable预览器,在开发过程中可以动态预览Lite Wearable应用的界面呈现效果,默认不自 动下载,需手动勾选下载
  1. 开发工具常见设置:
  • 自动提示忽略大小写: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+/
  1. DevEco Studio项目结构:

  • MyApplication:项目的项目名

    • .gradle:是项目管理工具gradle的信息
    • .idea:是开发工具的信息
    • build:程序编译运行后会自动生成
    • entry:是应用主模块。在一个项目中,有且只有一个,所有的代码都写在这里(重要)
      • build:这个文件夹里面有一个R文件,记录每一个资源文件对应的id。里面的内容是自动生成的。 R文件是一个压缩包,里面装的ResourceTable这个类的字节码文件
      • libs:第三方jar包存放的位置
      • src:主要代码
        • main:是我们自己写的主要代码。

          • java:里面是我们写的所有代码。
          • resources:里面是我们跟界面相关的资源文件。
          • config.json:是界面相关所有配置信息,每一个界面都需要在这个里面进行配置。
      • 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 如何运行应用

  1. Tools—>Device Manager中,登录账号

  2. 选择P40手机,点击右侧青色三角启动

  3. 点击编译器上方的绿色三角启动项目

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 程序的启动过程

  1. 解析config.json文件
  2. 初始化入口MyApplication
  3. 获取第一个要启动界面的全类名MainAbility
  4. 运行代码,并启动第一个界面MainAbility
  5. 运行界面中的切片MainAbilitySlice
  6. 加载xml文件Layout_ability_main,展示内容

2.2 第二个入门应用-页面跳转

  • 设计思路:

    1. 在第一个界面添加一个按钮
    2. 写第二个界面
    3. 添加跳转关系
  • 界面布局:在鸿蒙UI中提供了两种编写布局的方式

    • 在XML文件中声明UI布局:比较简单,常用
    • 在代码中创建布局

    在此,我们用XML布局第一个页面,用代码布局第二个页面

2.2.1 XML文件编写第一个页面

打开src—>main—>resourses—>base—>layout下的ability_main.xml文件,创建一个文本和一个按钮

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos: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"/><Buttonohos: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 {@Overridepublic 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;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到按钮idbtu = (Button)findComponentById(ResourceTable.Id_but1);//给按钮添加一个点击事件,点击后执行本类中onClick方法btu.setClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic 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 {@Overridepublic 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());}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}
}
class MyListener implements Component.ClickedListener {//编写类作为接口的实现类@Overridepublic void onClick(Component component) {//component:所有组件的父类//参数:被点击的组件对象//访问子类中特有方法:向下转型Button btu = (Button)component;btu.setText("第一种单击事件写法");}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Buttonohos: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方法得以访问@Overridepublic 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);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onClick(Component component) {//component:所有组件的父类//参数:被点击的组件对象//访问子类中特有方法:向下转型Button btu = (Button)component;btu.setText("第二种单击事件写法");text1.setText("被点击了");}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="text"ohos:text_size="100"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.1.1.3 匿名内部类

实例:点击“点我”按钮,按钮文字将变为“第三种单击事件写法”,文本框内文字变为“被点击了”

MainAbilitySlice文件:

package com.spring1227.listener3application.slice;import com.spring1227.listener3application.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 {@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//第三种单击事件写法:匿名内部类//弊端:写的代码只能使用一次//找到组件Button but1 = (Button)findComponentById(ResourceTable.Id_but1);Text text1 = (Text)findComponentById(ResourceTable.Id_text1);//给按钮绑定一个单击事件but1.setClickedListener(new Component.ClickedListener() {@Overridepublic void onClick(Component component) {Button btu = (Button)component;btu.setText("第三种单击事件写法");text1.setText("被点击了");}});}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="text"ohos:text_size="100"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.1.1.4 方法引用

实例:点击“点我”按钮,按钮文字将变为“第四种单击事件写法”,文本框内文字变为“被点击了”

MainAbilitySlice文件:

package com.spring1227.listener4application.slice;import com.spring1227.listener4application.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 {Text text1 = null;@Overridepublic 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);//给按钮绑定一个单击事件but1.setClickedListener(this::onClick);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}public void onClick(Component component) {Button btu = (Button)component;btu.setText("第四种单击事件写法");text1.setText("被点击了");}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="text"ohos:text_size="100"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.2 双击事件

接口名:DoubleClickedListener

实例:双击“点我”按钮,按钮文字将变为“双击事件”,文本框内文字变为“双击”

MainAbilitySlice文件:

package com.spring1227.doublelistenerapplication.slice;import com.spring1227.doublelistenerapplication.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.DoubleClickedListener {Text text1 = null;//设为成员变量,使onDoubleClick方法得以访问@Overridepublic 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);//绑定事件//想点击谁就给谁绑定事件//当点击按钮时,会执行本类中的onDoubleClick方法but1.setDoubleClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onDoubleClick(Component component) {text1.setText("双击");}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="text"ohos:text_size="100"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.3 长按事件

接口名:LongClickedListener

实例:长按“点我”按钮,按钮文字将变为“长按事件”,文本框内文字变为“长按”

MainAbilitySlice文件:

package com.spring1227.longlistenerapplication.slice;import com.spring1227.longlistenerapplication.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.LongClickedListener {Text text1 = null;//设为成员变量,使onLongClicked方法得以访问@Overridepublic 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);//绑定事件//想点击谁就给谁绑定事件//当点击按钮时,会执行本类中的onLongClick方法but1.setLongClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onLongClicked(Component component) {text1.setText("长按");}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="Text"ohos:text_size="100"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.4 滑动事件

接口名:TouchEventListener

实例:当在屏幕做上下左右滑动操作时,文本内容对应显示文字

MainAbilitySlice文件:

package com.spring1227.slideapplication.slice;import com.spring1227.slideapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener {Text text1 = null;//设为成员变量,使onTouchEvent方法得以访问int count = 0;//检验滑动操作时,代码是否会不断去调用TouchEvent方法@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到整个布局对象和文本对象DirectionalLayout dl = (DirectionalLayout)findComponentById(ResourceTable.Id_dl);text1 = (Text)findComponentById(ResourceTable.Id_text1);//给整个布局添加滑动事件//当在整个布局上滑动时,会调用本类中的TouchEvent方法//在按下移动松开过程中,代码会不断去调用本类中的TouchEvent方法dl.setTouchEventListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}//记录按下时手指的位置,在鸿蒙中,坐标轴x在屏幕上方从左到右,坐标轴y在屏幕左侧从上到下float startx = 0;float starty = 0;@Overridepublic boolean onTouchEvent(Component component, TouchEvent touchEvent) {count++;//计录调用onTouchEvent方法的次数//参数1:component表示滑动的那个组件(布局也是组件)//参数2:touchEvent表示动作对象(按下,滑动,抬起)//获取当前手指对屏幕进行的操作(按下,滑动,抬起)int action = touchEvent.getAction();//1表示按下操作:PRIMARY_POINT_DOWN//2表示松开操作:PRIMARY_POINT_UP//3表示滑动/移动操作:POINT_MOVEif(action == TouchEvent.PRIMARY_POINT_DOWN){//表示按下
//            text1.setText("按下"+count);//获取按下时手指的位置MmiPoint point = touchEvent.getPointerPosition(0);startx = point.getX();starty = point.getY();//            text1.setText(x+"----"+y);}else if(action == TouchEvent.POINT_MOVE ){//表示移动
//            text1.setText("移动"+count);
//
//            MmiPoint point = touchEvent.getPointerPosition(0);
//            x = point.getX();
//            y = point.getY();
//            text1.setText(x+"----"+y);}else if (action == TouchEvent.PRIMARY_POINT_UP){//表示松开
//            text1.setText("松开"+count);MmiPoint point = touchEvent.getPointerPosition(0);float endx = point.getX();float endy = point.getY();String str = "";//按下松开位置对比,并设置一定容忍度if(endx > startx && Math.abs(endy - starty) < 100){str = "右滑";}else if(endx < startx && Math.abs(endy - starty) < 100){str = "左滑";}else if(endy > starty && Math.abs(endx - startx) < 100){str = "下滑";}else if(endy < starty && Math.abs(endx - startx) < 100){str = "上滑";} else {str = "啥也不是";}text1.setText(str);}//如果为true,表示所有动作都会触发当前方法并且执行对应代码//如果为flase,表示只有第一个动作会触发当前方法并执行对应代码//后续动作就不再触发//按下(第一动作)-滑动-松开return true;}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutohos:id="$+id:dl"xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"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"/></DirectionalLayout>

3.5 案例

3.5.1 案例1-多按钮被点击

实例:点击相应按钮,文本框对相应显示文字

MainAbilitySlice文件:

package com.spring1227.multibuttonapplication.slice;import com.spring1227.multibuttonapplication.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;Button login;Button register;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到组件text1 = (Text)findComponentById(ResourceTable.Id_text1);login = (Button)findComponentById(ResourceTable.Id_login);register = (Button)findComponentById(ResourceTable.Id_register);//给按钮绑定事件login.setClickedListener(this);register.setClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onClick(Component component) {//先做一个判断,是按了哪个按钮if(component == login){//点击了登录按钮text1.setText("点击了登录按钮");}else if(component == register){//点击注册按钮text1.setText("点击了注册按钮");}}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutohos:id="$+id:dl"xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"ohos:height="match_content"ohos:width="match_content"ohos:text="Text"ohos:text_size="100"/><Buttonohos:id="$+id:login"ohos:height="match_content"ohos:width="match_content"ohos:text="登录"ohos:text_size="100"ohos:background_element="cyan"/><Buttonohos:id="$+id:register"ohos:height="match_content"ohos:width="match_content"ohos:text="注册"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.5.2 案例2-双击点赞

实例:双击屏幕或单击图标变红心,单击图标变空心

MainAbilitySlice文件:

package com.spring1227.doubleclicklikeapplication.slice;import com.spring1227.doubleclicklikeapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;public class MainAbilitySlice extends AbilitySlice implements Component.DoubleClickedListener, Component.ClickedListener {Image image;DirectionalLayout dl;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//找到组件image = (Image)findComponentById(ResourceTable.Id_img);//找到布局组件dl = (DirectionalLayout)findComponentById(ResourceTable.Id_dl);//添加事件dl.setDoubleClickedListener(this);image.setClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}//做个标记:如果为true,则已经点赞,如果为false,则未点赞boolean flag = false;@Overridepublic void onDoubleClick(Component component) {if (component == dl && flag == false) {//双击了屏幕并且此时为空心image.setImageAndDecodeBounds(ResourceTable.Media_red);flag = !flag;//表示此时已点赞}}@Overridepublic void onClick(Component component) {if(component == image && flag == true){//单击了图标并且此时为红心image.setImageAndDecodeBounds(ResourceTable.Media_white);flag = !flag;//表示此时已取消点赞}else if(component == image && flag == false){//单击了图标并且此时为空心image.setImageAndDecodeBounds(ResourceTable.Media_red);flag = !flag;//表示此时已点赞}}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutohos:id="$+id:dl"xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Imageohos:id="$+id:img"ohos:height="match_content"ohos:width="match_content"ohos:image_src="$media:white"/></DirectionalLayout>

3.5.3 案例3-单击出现随机文本

实例:单击按钮,出现一个随机文本

MainAbilitySlice文件:

package com.spring1227.randompoemapplication.slice;import com.spring1227.randompoemapplication.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;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Random;public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {String[] poem;Text text1;Button but1;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);try {//用来拼接读取到的所有数据StringBuffer sb = new StringBuffer();//资源管理器:读取文件并加载出来Resource resourse = this.getResourceManager().getResource(ResourceTable.Profile_poem);//resourse是一个字节流,利用字节流可以读取文件中的内容,但是读中文可能出问题,所以转化为字符串BufferedReader br = new BufferedReader(new InputStreamReader(resourse));String line;while((line = br.readLine())!=null){sb.append(line);//拼接每行读到的数据}//释放资源br.close();//当代码运行到这里,资源文件poem.txt中的内容就都在sb当中了//利用文本文档中的“---”将数据切割分段poem = sb.toString().split("---");//当点击按钮后,给文本框一个随机的小诗//找到文本组件按钮组件text1 = (Text)findComponentById(ResourceTable.Id_text1);but1 = (Button)findComponentById(ResourceTable.Id_btu1);//绑定事件but1.setClickedListener(this);} catch (IOException e) {e.printStackTrace();} catch (NotExistException e) {e.printStackTrace();}}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onClick(Component component) {//点击按钮后从数组随机拿一个诗,放到文本框中Random r = new Random();//获取随机索引int index = r.nextInt(poem.length);//通过随机索引获取小诗String randomPoem = poem[index];//将小诗放到文本框中text1.setText(randomPoem);}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"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"ohos:multiple_lines="true"/><!--       multiple_lines="true"    true表示如果文本过长会自动换行--><Buttonohos:id="$+id:btu1"ohos:height="match_content"ohos:width="match_content"ohos:text="点我换诗"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.5.4 案例4-单击出现随机图片

实例:单击按钮,出现一张随机图片

MainAbilitySlice文件:

package com.spring1227.randomphotoapplication.slice;import com.spring1227.randomphotoapplication.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.Image;import java.util.ArrayList;
import java.util.Random;public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {Image img;Button btu1;ArrayList<Integer>list = new ArrayList<>();@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);//定义一个集合或数组来存储所有图片list.add(ResourceTable.Media_girl1);list.add(ResourceTable.Media_girl2);list.add(ResourceTable.Media_girl3);list.add(ResourceTable.Media_girl4);list.add(ResourceTable.Media_girl5);//找到对应的组件img = (Image)findComponentById(ResourceTable.Id_img);btu1 = (Button)findComponentById(ResourceTable.Id_but1);//绑定事件btu1.setClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}@Overridepublic void onClick(Component component) {//当点击按钮时修改图片内容Random r = new Random();//获取随机索引int index = r.nextInt(list.size());//通过随机索引索引,获取随机元素int randomImg = list.get(index);img.setImageAndDecodeBounds(randomImg);}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Imageohos:id="$+id:img"ohos:height="match_content"ohos:width="match_content"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="选老婆"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

3.5.4 案例5-统计点击次数

实例:统计在10s内点击按钮次数

MainAbilitySlice文件:

package com.spring1227.countapplication.slice;import com.spring1227.countapplication.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;Button btu1;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);text1 = (Text)findComponentById(ResourceTable.Id_text1);btu1 = (Button)findComponentById(ResourceTable.Id_but1);btu1.setClickedListener(this);}@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}//如果flag是true,认为是第一次点击boolean flag = true;long starttime = 0;int count = 0;@Overridepublic void onClick(Component component) {count++;//记录被点击次数if(flag){//第一次点击//记录当前时间starttime = System.currentTimeMillis();//第一次点击开始游戏开始,修改文本框内容btu1.setText("请狂点");flag = false;}else{if(System.currentTimeMillis() - starttime <=10000){text1.setText(count+"次 "+(System.currentTimeMillis() - starttime)/1000.0+"s");}else {btu1.setText("游戏结束!");//取消按钮的点击事件btu1.setClickable(false);//禁用按钮}}}
}

ability_main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:alignment="center"ohos:orientation="vertical"><Textohos:id="$+id:text1"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"/><Buttonohos:id="$+id:but1"ohos:height="match_content"ohos:width="match_content"ohos:text="开始"ohos:text_size="100"ohos:background_element="red"/></DirectionalLayout>

四、组件

  • 屏幕中展示出来的元素称为组件

  • 顶级父类:Component

  • 组件分类:

    • 显示类组件:只负责数据显示,无法交互
    • 交互类组件:可交互
    • 布局类组件:布局是一种特殊的组件

4.1 显示类组件

4.1.1 Text文本框

4.1.2 Image图片

4.1.3 CommonDialog普通弹框

4.1.4 ToastDialog信息提示

4.1.5 Clock时钟

4.1.6 TickTimer定时器

4.1.7 ProgressBar进度条

4.1.8 RoundProgressBar

4.2 交互类组件

4.2.1 TextField文本输入框

4.2.2 Button按钮

4.2.3 CheckBox多选框

4.2.4 RadioButton单选框

4.2.5 Switch开关组件

4.2.6 Slider滑块

4.2.7 ListContainer

4.2.8 Picker 滑动选择器

4.2.9 DatePicker和TimePicker

4.3 美化组件

4.3.1 美化组件分类

  • 美化外形

    • 组件外形
    • 组件边框
    • 背景颜色
    • 背景渐变
  • 美化状态:组件在不同状态时显示不同的样式,暂时掌握三种
    • 默认状态
    • 按下状态
    • 转中状态

4.3.2 graphic包中shape标签

在graphic包中新建xml文件,根标签为:shape就可以自定义组件的形状

4.3.3 graphic包中的state-container标签

4.3.4 实际开发中的美化标签

  1. 美工已经做好图片,直接在state-container中指定状态关联图片
  2. 美工就是不做,针对每一种状态都要写对应的xml文件

4.4 布局类组件

五、布局

  • 多个组件的摆放方式就是布局
  • 顶级父类:ComponentContainer
  • 组件必须添加到布局中才能显示出来
  • 组件的展示方式有:线性布局,相对布局,绝对布局,格子布局等
  • 布局一般以“Layout”结尾,如DirectionalLayout、DependentLayout等
  • 组件在未被添加到布局中时,既无法显示也无法交互,因此一个用户界面至少包含一个布局。

5.1 布局分类

5.1.1 线性布局DirectionalLayout

5.1.2 相对布局DependentLayout

5.1.3 格子布局TableLayout

5.1.4 绝对布局PositionLayout

  • 可以指定组件的具体位置

5.1.5 自适应布局AdaptiveBoxLayout

  • 指定一行的范围
  • 屏幕范围小,每行就展示一个,屏幕范围大,就展示多个 底层还不是太稳定

5.2 组件和布局的包含关系

  • 布局可以理解为是一个容器,可以容纳组件和其他布局,并规定他们如何进行显示
  • 组件在未被添加到布局中时, 既无法显示也无法交互,因此一个用户界面至少包含一个布局
  • Java UI框架提供了一些标准布局功能的容器,它们继承自ComponentContainer,一般以“Layout”结尾,如 DirectionalLayout、DependentLayout等

5.3 组件树

在一个界面中,最外层是一定是布局,在布局里面可以有组件,也可以有其他布局

布局可以理解为是多个组 件形成的那个整体

六、Ability

  • Ability是应用所具备能力的抽象,也是应用程序的重要组成部分
  • 一个应用可以具备多种能力(即可以包含多个 Ability)
  • HarmonyOS支持应用以Ability为单位进行部署

6.1Ability分类

6.1.1 Feature Ability(FA)

FA支持Page Ability,简单理解就是手机应用中的一个界面。一个界面就是一个FA

Page模板是FA唯一支持的模板,用于提供与用户交互的能力

一个Page实例可以包含一组相关页面,每个页面用 一个AbilitySlice实例表示

6.1.2 Particle Ability(PA)

FA是有有界面的,Particle Ability(PA)是无界面的,简单理解就是可以运行在后台的一个服务。

PA支持Service Ability和Data Ability:

  • Service模板:用于提供后台运行任务的能力

  • Data模板:用于对外部提供统一的数据访问抽象。一般是跟数据相关的,比如:要运行访问数据库,那么就可以用 PA中的Data模板

6.2 Feature Ability(FA)

  • 页面FA和切片之间的关系
  • 页面中如何添加多个切片
  • 页面之间的跳转
    想要学习跳转,首先要知道一个知识点就是意图,表示我跳转的时候,跳到哪里以及携带什么参数进行跳转?

6.3 Intent

Intent是对象之间传递信息的载体

例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过 Intent指定启动的目标同时携带相关数据

Intent的构成元素包括Operation与Parameters:

  • Operation:表示要跳转的目的地
  • Parameters:跳转时所携带的数据

6.4 页面跳转的所有情况

  • 同一个页面中,不同切片之间的跳转(无参,有参,有返回结果)
  • 不同页面中,主切片跟主切片之间的跳转(无参,有参,有返回结果)
  • 不同页面中,主切片跟非主切片之间的跳转(无参,有参,有返回结果)

时,既无法显示也无法交互,因此一个用户界面至少包含一个布局。

5.1 布局分类

5.1.1 线性布局DirectionalLayout

5.1.2 相对布局DependentLayout

5.1.3 格子布局TableLayout

5.1.4 绝对布局PositionLayout

  • 可以指定组件的具体位置

5.1.5 自适应布局AdaptiveBoxLayout

  • 指定一行的范围
  • 屏幕范围小,每行就展示一个,屏幕范围大,就展示多个 底层还不是太稳定

5.2 组件和布局的包含关系

  • 布局可以理解为是一个容器,可以容纳组件和其他布局,并规定他们如何进行显示
  • 组件在未被添加到布局中时, 既无法显示也无法交互,因此一个用户界面至少包含一个布局
  • Java UI框架提供了一些标准布局功能的容器,它们继承自ComponentContainer,一般以“Layout”结尾,如 DirectionalLayout、DependentLayout等

5.3 组件树

在一个界面中,最外层是一定是布局,在布局里面可以有组件,也可以有其他布局

布局可以理解为是多个组 件形成的那个整体

[外链图片转存中…(img-bI8jBV6V-1633163777221)]

六、Ability

  • Ability是应用所具备能力的抽象,也是应用程序的重要组成部分
  • 一个应用可以具备多种能力(即可以包含多个 Ability)
  • HarmonyOS支持应用以Ability为单位进行部署

6.1Ability分类

6.1.1 Feature Ability(FA)

FA支持Page Ability,简单理解就是手机应用中的一个界面。一个界面就是一个FA

Page模板是FA唯一支持的模板,用于提供与用户交互的能力

一个Page实例可以包含一组相关页面,每个页面用 一个AbilitySlice实例表示

6.1.2 Particle Ability(PA)

FA是有有界面的,Particle Ability(PA)是无界面的,简单理解就是可以运行在后台的一个服务。

PA支持Service Ability和Data Ability:

  • Service模板:用于提供后台运行任务的能力

  • Data模板:用于对外部提供统一的数据访问抽象。一般是跟数据相关的,比如:要运行访问数据库,那么就可以用 PA中的Data模板

6.2 Feature Ability(FA)

  • 页面FA和切片之间的关系
  • 页面中如何添加多个切片
  • 页面之间的跳转
    想要学习跳转,首先要知道一个知识点就是意图,表示我跳转的时候,跳到哪里以及携带什么参数进行跳转?

6.3 Intent

Intent是对象之间传递信息的载体

例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过 Intent指定启动的目标同时携带相关数据

Intent的构成元素包括Operation与Parameters:

  • Operation:表示要跳转的目的地
  • Parameters:跳转时所携带的数据

6.4 页面跳转的所有情况

  • 同一个页面中,不同切片之间的跳转(无参,有参,有返回结果)
  • 不同页面中,主切片跟主切片之间的跳转(无参,有参,有返回结果)
  • 不同页面中,主切片跟非主切片之间的跳转(无参,有参,有返回结果)

HarmonyOS笔记相关推荐

  1. HarmonyOS鸿蒙学习笔记(12)@Link的作用

    通过HarmonyOS鸿蒙学习笔记(5)@State作用说明和简单案例一文我们知道@State修饰的变量发生变化时,会刷新相关页面更新UI.如果是子组件想要改变父组件的状态从而刷新UI改怎么办呢?比如 ...

  2. HarmonyOS鸿蒙学习笔记(2)路由ohos.router的使用

    ohos.router路由入门指南 前言 路由跳转传递和接收参数 参考资料 前言 本文以eTS-3.1.6.6位版本来说明ohos.router的使用,重点来说明ohos.router怎么传递和接收参 ...

  3. HarmonyOS(鸿蒙)App项目实战(1)运动手表篇学习笔记

    HarmonyOS(鸿蒙)APP项目实战(1)运动手表篇学习笔记 前言 概括 创建项目 创建主页面 创建index中的组件 设定index中组件的样式 为主页面添加应有的功能 创建倒计时页面 创建da ...

  4. 鸿蒙系统内核学习笔记(一)-HarmonyOS 轻内核基础功能

    1.1 进程 1.1.1 基本概念 从系统的角度看,进程是资源管理单元.进程可以使用或等待 CPU.使用内存空间等系统资源,并独立于其它进程运行. HarmonyOS 内核的进程模块可以给用户提供多个 ...

  5. 华为鸿蒙系统学习笔记11-鸿蒙(HarmonyOS)2.0方舟编译器官方网址开源地址

    鸿蒙(HarmonyOS)2.0: 开源项目:https://www.openatom.org/openharmony 代码仓库:https://openharmony.gitee.com 方舟编译器 ...

  6. 鸿蒙OS应用开发_基础篇_编写第一个HarmonyOs应用_体会HarmonyOs的一次开发多端部署_以及分布式任务调度_IDE安装_了解应用组件以及应用布局---HarmonyOs开发工作笔记001

    这个系列的文章,跟大家一起学习HarmonyOs系统的应用开发, 先给出harmonyOs开发手册文档,非常详细: https://developer.harmonyos.com/cn/docs/do ...

  7. 鸿蒙应用开发培训笔记01:HarmonyOS介绍

    文章目录 零.本讲学习目标 一.鸿蒙系统理念与关键技术 (一)智能终端产业飞速发展带来历史性机遇 (二)HarmonyOS+超级终端,带给消费者的不一样 (三)HarmonyOS 开启万物互联时代的一 ...

  8. 鸿蒙2.0设备开发教程】小熊派HarmonyOS 鸿蒙笔记

    HarmonyoS网络应用开发连接华为loT平台 主要内容: 本节主要介绍: 如何使用华为loT平台·设备如何对接华为loT平台 步骤; 1.华为loT平台介绍2.华为loT平台产品创建3.设备对接华 ...

  9. Harmonyos应用开发第一次笔记

    JS FA 应用的 JS 模块 (entry/src/main/js/module) 的典型开发目录结构如下: 目录结构中文件分类如下: .hml 结尾的 HML 模板文件,这个文件用来描述当前页面的 ...

  10. 《HarmonyOS开发 - IPC Camera开发笔记》第2章 HiSpark IPC Camera开发环境搭建(基于V1.1.4)

    开发环境: 开发系统:Ubuntu 20.04 Harmony版本:code-v1.1.4-LTS.tar HiSpark IPC Camera基于华为海思Hi3518芯片,支持LiteOS.Open ...

最新文章

  1. SAP MM PO中的Delivery Date并非保存在EKPO表里
  2. 基于模块度的社团检测算法
  3. spring boot 项目打成war包部署到服务器
  4. 原版英文书籍《Linux命令行》阅读记录7 | 原版英文书籍《Linux命令行》阅读记录7 | 一些键盘按键技巧...
  5. 解决ubuntu下不能mount windows 盘的问题
  6. spring较为常用注解
  7. vue加载中图片和加载失败图片的占位图
  8. python写电影推荐系统_Netflix电影推荐系统Python实现(协同过滤+矩阵分解)
  9. 【小记】谷歌浏览器安装Axure插件,无需下载
  10. JS 大陆香港台湾手机格式校验
  11. B2B,B2C,C2C,C2B,B2G
  12. spring boot打包本地idea跑能行,上线jar包跑不行 解决
  13. 1.1.6 LSDB同步
  14. 异域公主连接iOS怎么修改服务器,公主连结ios账号在电脑端登录方法 模拟器使用技巧分享...
  15. 人人美剧迅雷链接多线程和多进程爬虫分析
  16. 通过npm运行管理端界面并解决npm install安装报错
  17. 【TF-IDF算法+工具】实战分析关键词排名
  18. 又要去迪士尼了。。。
  19. 【开发工具】【objdump】反汇编工具objdump的使用
  20. 【毕业设计】深度学习二维码识别系统 - python opencv

热门文章

  1. 虚幻4引擎开发的手游_怎么使用虚幻4开发游戏?
  2. 读计算机专业买什么笔记本电脑好?你算问对人了
  3. 电赛日志——2016年TI杯大学生电子设计竞赛 A题:降压型直流开关稳压电源
  4. Windows如何注册Com组件
  5. cloudmusic:网易云爬虫
  6. RestClient操作索引库
  7. 高数 | 常用求极限方法总结
  8. win10环境下matlab2017b编译运行c++文件步骤
  9. 辐射4核能选项用计算机失败,辐射4NMM安装framework失败解决方法一览_游侠网
  10. xshell中文问号乱码