赞
踩
当新建完毕一个鸿蒙项目之后,自带有HelloWorld的代码
如下图所示,MainAbility(界面)包含一个或多个MainAbilitySlice(子界面)
MainAbilitySlice(子界面)包含要显示的内容
MainAbility是项目启动的第一个界面,在界面里面不是直接显示内容的。在界面里面展示的是子界面,我们也称之为切片slice。在子界面里面才是显示内容的,这也正是为什么我们的逻辑代码都要写在slice文件中
所有的模块,界面等信息,都会在这个文件中进行配置。鸿蒙启动之后,先解析这个文件,这个文件分为三类app deviceConfig module
{ "app": {//整个项目的配置,包含了厂商信息,版本号等 "bundleName": "com.example.myapplicationnewtest",//包名 "vendor": "example",//是应用开发厂商的描述,也就是开发公司的名字 "version": { "code": 1000000,//用户看到的版本号 "name": "1.0.0"//用户看不到的,只能公司内部人员使用的版本号 } }, "deviceConfig": {},//表示应用在设备删搞得配置信息,比如是否允许使用网络流量,是否支持设备未解锁状态直接启动等 "module": {//表示整个代码的配置信息,比如程序在运行时候的所有界面,以及第一个要启动的界面是谁 "package": "com.example.myapplicationnewtest",//包名 "name": ".MyApplication",//hap包的名字 "mainAbility": "com.example.myapplicationnewtest.MainAbility",//表示HAP包的入口名称 "deviceType": [//表示项目可以在哪些设备上运行,因为可能有多个设备,所以有个方括号,表示这些值可以写到一个数组里 "phone" ], "distro": {//表示HAP包的描述信息 "deliveryWithInstall": true,//当前HAP包是否可以支持随应用安装,一般为true "moduleName": "entry",//当前HAP的名称 "moduleType": "entry",//当前HAP的类型,有entry和feature "installationFree": false }, "abilities": [//表示当前模块内的所有Ability { "skills": [//表示Ability能接受到的Intent的特征 { "entities": [//表示能够接收的Intent的Ability的类别(视频,桌面应用) "entity.system.home" ], "actions": [//表示能够接收的Intent的action值 "action.system.home" ] } ], "orientation": "unspecified", "visible": true, "name": "com.example.myapplicationnewtest.MainAbility", "icon": "$media:icon",//表示Ability图标资源文件的索引,表示引用media目录下的icon资源 "description": "$string:mainability_description", "label": "$string:entry_MainAbility",//应用安装后用户设备显示的名称 "type": "page",//可以为page service或data "launchType": "standard"//表示启动模式,支持standard和singleton } ] } }
当程序刚开始启动的时候,会解析config.json中的信息,获取到第一个要加载的界面,也就是mainAbility,通过包名 + 类名定位到要运行的类MainAbility,所以界面启动,在这个界面里面又加载了MainAbilitySlice切片,在该切片中展示的内容为Layout包中的ability_main。
把HelloWorld界面改为第一个界面,并且添加一个按钮
写第二个界面SecondAbility
书写跳转关系
界面布局。这两种方式创建出的布局没有本质差别,但是XML方式较为方便简单,以后开发中,尽量用XML布局的方式
<?xml version="1.0" encoding="utf-8"?> <DependentLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:width="match_parent" ohos:height="match_parent" ohos:background_element="#000000"> <Text ohos:id="$+id:text" ohos:width="match_content" ohos:height="match_content" ohos:text="Hello World" ohos:text_color="white" ohos:text_size="32fp" ohos:center_in_parent="true"/> <Button ohos:id="$+id:button" ohos:width="match_content" ohos:height="match_content" ohos:text="Next" ohos:text_size="19fp" ohos:text_color="white" ohos:top_padding="8vp" ohos:bottom_padding="8vp" ohos:right_padding="80vp" ohos:left_padding="80vp" ohos:background_element="$graphic:background_button" ohos:below="$id:text" ohos:horizontal_center="true" /> </DependentLayout>
其中宽和高的取值分别可以是固定的数值,match_content以及match_parent
具体数值10表示以像素为单位,10vp表示以屏幕相对像素为单位。
content表示组件大小与它的内容占据大大小范围相适应
parent表示组件大小将扩展为父组件允许的最大值,它将占据父组件方向上的剩余大小
public class SecondAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); //super.setUIContent(ResourceTable.Layout_ability_second); //1.创建布局对象 DirectionalLayout dl = new DirectionalLayout(this); //2.创建文本对象 Text t = new Text(this); //设置内容 t.setText("第二个页面"); //设置文字大小 t.setTextSize(55); //设置文字颜色 t.setTextColor(Color.BLUE); //3.把文本对象添加到布局当中 dl.addComponent(t); //4.把布局添加到子界面当中 super.setUIContent(dl); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
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); //1.找到按钮 id btu = (Button) findComponentById(ResourceTable.Id_but1); //2.给按钮添加一个点击事件 //如果没有添加点击事件,那么用鼠标点击按钮之后是没有任何反应的。 //如果我们给按钮添加了点击事件,那么用鼠标点击按钮之后,就可以执行对应的代码 //理解方式: //给btu这个按钮添加了点击事件 //当我们用鼠标点击了btu这个按钮之后,就可以执行本类中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){ //只有点击了btu这个按钮之后,才进行跳转 //跳转到哪个页面中(意图) Intent i = new Intent(); //包含了要跳转的页面信息 Operation operation = new Intent.OperationBuilder() .withDeviceId("")//要跳转到哪个设备上,如果传递一个没有内容的字符串,表示跳转本机 .withBundleName("com.example.myapplication")//我要跳转到哪个应用上,小括号里面可以写报名 .withAbilityName("com.example.myapplication.SecondAbility")//要跳转的页面 .build();//表示将上面的三个信息进行打包 //把打包之后的operation设置到意图当中 i.setOperation(operation); //跳转页面 startAbility(i); } } }
最后运行结果如下两张图所示
这几天一直遇到个问题,我们都知道项目启动的首页面是MainAbility并且会自动加载MainAbilitySlice。那么问题来了,假设我又创建了一个ExampleAbility(创建Ability的时候,DEV会自动帮我们生成对应的slice文件和graphic里面的xml文件和layout里面的xml文件)那么我如何把ExampleAbility设置成我的首页面呢?
无外乎,在请教高人之后,他们给出了两种方法。
第一种比较傻的方法是我们都知道MainAbility和ExampleAbility内容几乎完全一样,所以我们可以在MainAbility中设置setMainRoute的路由为ExampleAbilitySlice即可。如下图所示。
package com.example.myexampleapplication;
import com.example.myexampleapplication.slice.ExampleAbilitySlice;
import com.example.myexampleapplication.slice.MainAbilitySlice;//以前用的,这个包用不上了
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(ExampleAbilitySlice.class.getName());
}
}
第二种方法我觉得很实用,我们需要修改config.json文件中的内容。主要是修改abilities中的文件
"abilities": [ { "orientation": "unspecified", "visible": true, "name": "com.example.myexampleapplication.MainAbility", "icon": "$media:icon", "description": "$string:mainability_description", "label": "$string:entry_MainAbility", "type": "page", "launchType": "standard" }, { "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "action.system.home" ] } ], "orientation": "unspecified", "name": "com.example.myexampleapplication.ExampleAbility", "icon": "$media:icon", "description": "$string:exampleability_description", "label": "$string:entry_ExampleAbility", "type": "page", "launchType": "standard" } ]
我们需要哪个Ability作为首界面,我们就把skills的内容复制给它,如上图我想要ExampleAbility作为首界面,因此我就把skills的内容复制到对应的数组对象里。最后用编程方式创建的Ability如下图所示
其余页面并未做任何更改,因此我们只需要修改ExampleAbilitySlice页面
package com.example.myexampleapplication.slice; import com.example.myexampleapplication.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.colors.RgbColor; import ohos.agp.components.Button; import ohos.agp.components.Text; import ohos.agp.components.Component; import ohos.agp.components.ComponentContainer; import ohos.agp.components.DirectionalLayout; import ohos.agp.components.element.ShapeElement; import ohos.agp.utils.Color; import ohos.agp.utils.LayoutAlignment; public class ExampleAbilitySlice extends AbilitySlice { //三个重写的方法均继承于AbilitySlice类,其又继承AbilityContext类,后者又继承Context接口 //继承关系DirectionLayout继承ComponentContainer类,后者又继承Component类,Component类又继承JAVA的Object类 @Override public void onStart(Intent intent) { //onStart和setUIContent都来自于AbilitySlice类 super.onStart(intent); //super.setUIContent(ResourceTable.Layout_ability_example); //声明布局 DirectionalLayout directionalLayout= new DirectionalLayout(getContext()); //设置布局大小 //setWidth和setHeight方法继承Component类 里面的参数继承ComponentContainer这个类。 directionalLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT); directionalLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT); //设置布局属性 //setOrientation来自本类,设置布局的方向 setPadding来自于Component设置布局间距。 directionalLayout.setOrientation(Component.VERTICAL); directionalLayout.setPadding(32,32,32,32); //getContext来自于AbilityContext,为什么这个地方可以写getContext呢?首先我们查阅继承关系可知道,这个地方的构造函数传参应该为Context类型的参数 //Text和DirectionLayout同理。而getContext是来自于AbilityContext这个类,然后这个类又继承Context接口,因此这个地方可以填getContext Text text=new Text(getContext()); //setText和setTextSize都是来自Text类中的方法,很好理解 text.setText("编码创建视图布局"); text.setTextSize(80); //setId是来自于Component这个类的方法,需要额外注意。 text.setId(100); //为组件添加对应布局的布局属性,设置文本的布局,调用DirectionLayout中的构造方法,这个构造方法可以传递两个参数,参数与上面一样。 DirectionalLayout.LayoutConfig layoutConfig=new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT); //alignment来自DirectionLayout.LayoutConfig属性,LayoutAlignment是引入的类 layoutConfig.alignment= LayoutAlignment.HORIZONTAL_CENTER; //setLayoutConfig来自于Component text.setLayoutConfig(layoutConfig); //将Text添加到布局中,addComponent来自于ComponentContainer directionalLayout.addComponent(text); //类似的还添加一个Button Button button=new Button(getContext()); //setMargins来自于ComponentContainer,同上 layoutConfig.setMargins(0,50,0,0); button.setLayoutConfig(layoutConfig); button.setText("更新信息"); button.setTextSize(50); //设置页面背景色,shapeElement来自于引入类,构造方法可以不传参! ShapeElement background=new ShapeElement(); //下面两个方法都来自于ShapeElement这个类,setRgbColor构造函数需要RgbColor类型的参数,于是只能new一个,来自于ohos.agp.colors.RgbColor; background.setRgbColor(new RgbColor(0,125,255)); background.setCornerRadius(25); //前面两个来自于Component类 button.setBackground(background); button.setPadding(10,10,10,10); //来自于Text类,为什么Button可以使用Text这个类中的方法呢?Button继承了Text类这个方法!注意看源代码! button.setTextColor(Color.WHITE); button.setClickedListener(new Component.ClickedListener() {//点击事件方法来自于Component @Override public void onClick(Component component) { System.out.println(this); } }); //addComponent来自于ComponentContainer类 directionalLayout.addComponent(button); //将布局作为根布局添加到视图树中 super.setUIContent(directionalLayout); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。