整体框架:
目标效果:一组相关页面(MainAbility)中的一个页面(MainAbilitySlice)中有两个按钮:点第一个按钮进入同一组相关页面(相同的MainAbility)的不同页面(不同的NewAbilitySlice),再点页面中的按钮回到原组相关页面(MainAbility); 点第二个按钮进入不同的一组相关页面(不同的SecondAbility)的不同页面(不同的SecondAbilitySlice),再点页面中的按钮回到原组相关页面(MainAbility)。
各个部分理解:
1.MainAbility
package com.example.abilityintent01;
import com.example.abilityintent01.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class MainAbility extends Ability {
@Override//重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,
// 通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了
//开发者必须重写该方法,并在此配置默认展示的AbilitySlice。
public void onStart(Intent intent) {//Intent是系统的基本通信组件,对象之间传递信息的载体
super.onStart(intent);//intent,指示启动此功能时携带的信息
//onStart():初始化一个Ability时回调(该回调在其生命周期过程中仅触发一次)
//通过setMainRoute()方法来指定默认展示的AbilitySlice
super.setMainRoute(MainAbilitySlice.class.getName());
//getName():以 String 的形式返回由此类对象表示的实体的名称
}
}
2.MainAbilitySlice
package com.example.abilityintent01.slice;
import com.example.abilityintent01.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
public class MainAbilitySlice extends AbilitySlice {
private Text backValueText;//创建一个Text类实例化对象,用于文本显示
@Override//由于AbilitySlice承载具体的页面,开发者必须重写AbilitySlice的onStart()回调
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
//设置页面,引用xml文件,下面才可以从layout文件夹下的ability_main.xml中寻找资源ID
//start entering the NewAbilitySlice(第一个按钮)
//component是提供用户界面 (UI) 的基本组件
Component enterNewAbilitySliceButton = findComponentById(ResourceTable.Id_enter_newAbilitySlice);
//findComponentById():Finds a component in the XML file based on the resource ID.
// 如果找到记录,则返回与 ID 对应的组件;否则返回空值
//Id_enter_newAbilitySlice对应ability_main.xml文件中的Button id
enterNewAbilitySliceButton.setClickedListener(listener -> presentForResult(new NewAbilitySlice() , new Intent(), 0));
//setClickedListener()为component中的单击事件注册侦听器listener,当单击的位置位于组件的显示区域内时,将触发单击事件,并通知所有已注册的观察者
//setClickedListener(Component.ClickedListener listener),
// Component.ClickedListener是个接口,包含方法onClick(Component component),指示一个component已经被点击,其中添加按钮被点击需要执行的操作
// -> 是Lambda表达式 语法:(实现的这个接口中的抽象方法中的形参列表 -> 抽象方法的处理)
// presentForResult()跳转到目标slice,并返回目标slice调用setResult()返回其设置的Intent data
//requestCode是自定义的请求码,不能为负数
//start entering the SecondAbility page(第二个按钮)
//Component enterSecondAbilityButton = findComponentById(ResourceTable.Id_enter_second);
//enterSecondAbilityButton.setClickedListener(component -> startEnterSecondAbility());
findComponentById(ResourceTable.Id_enter_second).setClickedListener(component -> startEnterSecondAbility());
backValueText = (Text) findComponentById(ResourceTable.Id_main_text);//(Text):将返回的组件component转化为Text类型,此步为多余
}
/**
* Result of presentForResult()
*/
@Override
protected void onResult(int requestCode, Intent resultIntent) {
if (requestCode != 0 || resultIntent == null) {
return;
}
String result = resultIntent.getStringParam("key");
//getStringParam():returns the string value of the parameter matching the given key
backValueText.setText(result);//指示要在文本组件中显示的文本
}
/**
* Explicit Startup
*/
private void startEnterSecondAbility() {
//通过构造包含BundleName与AbilityName的Operation对象,可以启动一个Ability、并导航到该Ability
Intent intent = new Intent();
//通过Intent中的OperationBuilder类构造operation对象
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")//指定设备标识(空串表示当前设备)
.withBundleName(getBundleName())//应用包名
.withAbilityName("com.example.abilityintent01.SecondAbility")//Ability名称
.build();
intent.setOperation(operation);// 把operation设置到intent中
intent.setParam("key", "我从MainAbility进到了SecondAbility");
startAbilityForResult(intent, 1);
}
@Override
//用于返回结果的回调
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode != 0 || resultData == null) {//SecondAbility返回的resultCode==0
return;
}
String result = resultData.getStringParam("key");
backValueText.setText(result);//将返回的string用于文本显示
}
}
3.NewAbilitySlice
package com.example.abilityintent01.slice;
import com.example.abilityintent01.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
public class NewAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main_new);
Component newToMainButton = findComponentById(ResourceTable.Id_new_to_main);
newToMainButton.setClickedListener(component -> terminate());
//terminate():摧毁当前ability slice,并返回setResult()设置的数据集
//If the slice to be destroyed is the only slice of its host ability, the ability will also be destroyed
}
@Override
public void onActive() {
super.onActive();
Intent intent = new Intent();
intent.setParam("key", "我从NewAbilitySlice跳回来咯");
setResult(intent);
//设置在销毁ability slice时要返回的数据。
//当ability slice调用 terminate()方法时,当前方法的结果数据集将传输到调用方。
}
//可以使用此方法实现重新初始化,也可以使用 intent 参数调整 UI。
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
4.SecondAbility
package com.example.abilityintent01;
import com.example.abilityintent01.slice.SecondAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class SecondAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(SecondAbilitySlice.class.getName());
}
@Override
protected void onActive() {
super.onActive();
Intent intent = new Intent();
intent.setParam("key", "我从SecondAbility跳回来啦,打我呀,我又跳出去啦,又跳回来啦,呀呀呀");
setResult(0, intent);//0为当前Ability销毁后返回的resultCode
}
}
5.SecondAbilitySlice
package com.example.abilityintent01.slice;
import com.example.abilityintent01.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
public class SecondAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_second);
Component secondBackFirstButton = findComponentById(ResourceTable.Id_second_back_first);
secondBackFirstButton.setClickedListener(component -> terminate());
Text showParametersText = (Text) findComponentById(ResourceTable.Id_second_text);
showParametersText.setText(intent.getStringParam("key"));
}
@Override
//使得Page导航到当前AbilitySlice,使Page进入Active状态(应用与用户交互)
public void onActive() {
super.onActive();
}
@Override
//可以使用此方法实现重新初始化,也可以使用 intent 参数调整 UI。
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
6.对Ability页面的标题栏进行修改
在config.json文件中,找到"abilities"(表示当前模块内的所有Ability)
找到"label"(表示Ability对用户显示的名称。取值可以是Ability名称,也可以是对该名称的资源索引)
按住Ctrl,左键点击,可以跳转到被引用的"string.json"文件,进而修改对应字段