Getting started with HelloWorld
When a new Hongmeng project is completed, it comes with HelloWorld code
- Inclusion relationships in pages
As shown in the figure below, the MainAbility (Interface) contains one or more MainAbilitySlice (sub interfaces)
The MainAbilitySlice (sub interface) contains the content to be displayed
MainAbility is the first interface for project startup. The content is not directly displayed in the interface. The sub interface displayed in the interface is also called slice. The content is displayed in the sub interface, which is why our logic code should be written in the slice file
- Configuration file config.json
All modules, interfaces and other information will be configured in this file. After Hongmeng starts, first parse this file, which is divided into three types: app deviceConfig module
{ "app": {//The configuration of the whole project includes manufacturer information, version number, etc "bundleName": "com.example.myapplicationnewtest",//Package name "vendor": "example",//Is the description of the application developer, that is, the name of the development company "version": { "code": 1000000,//Version number seen by the user "name": "1.0.0"//The version number that cannot be seen by the user can only be used by internal personnel of the company } }, "deviceConfig": {},//Indicates the configuration information obtained by the application in the device deletion, such as whether the network traffic is allowed, whether the device can be started directly without unlocking, etc "module": {//It represents the configuration information of the whole code, such as all interfaces of the program when running, and who is the first interface to start "package": "com.example.myapplicationnewtest",//Package name "name": ".MyApplication",//The name of the hap package "mainAbility": "com.example.myapplicationnewtest.MainAbility",//Represents the entry name of the HAP package "deviceType": [//Indicates which devices the project can run on. There may be multiple devices, so there is a square bracket, indicating that these values can be written to an array "phone" ], "distro": {//Represents the description of the HAP package "deliveryWithInstall": true,//Whether the current HAP package can support installation with the application, which is generally true "moduleName": "entry",//The name of the current HAP "moduleType": "entry",//The current HAP type includes entry and feature "installationFree": false }, "abilities": [//Indicates all abilities in the current module { "skills": [//Indicates the characteristics of Intent acceptable to Ability { "entities": [//Indicates the category of the Ability of the received Intent (video, desktop application) "entity.system.home" ], "actions": [//Indicates the action value of the Intent that can be received "action.system.home" ] } ], "orientation": "unspecified", "visible": true, "name": "com.example.myapplicationnewtest.MainAbility", "icon": "$media:icon",//Indicates the index of the Ability icon resource file and refers to the icon resource in the media directory "description": "$string:mainability_description", "label": "$string:entry_MainAbility",//The name displayed by the user's device after application installation "type": "page",//It can be page service or data "launchType": "standard"//Indicates the startup mode, and supports standard and singleton } ] } }
- Program startup process
When the program starts, it will parse the information in config.json to get the first interface to be loaded, that is, mainability. Locate the class mainability to be run through the package name + class name, so the interface starts. The MainAbilitySlice slice is loaded in this interface, and the content displayed in this slice is the ability in the Layout package_ main.
Page jump function
Change the HelloWorld interface to the first interface and add a button
Write the second interface SecondAbility
Writing jump relationship
Interface layout. There is no essential difference between the layouts created by the two methods, but XML is more convenient and simple. In future development, try to use XML layout
- Declare UL layout in 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>
The values of width and height can be fixed values respectively, match_content and match_parent
The specific value 10 is expressed in pixels, and 10vp is expressed in relative pixels of the screen.
Content indicates that the component size is suitable for the large size range occupied by its content
Parent indicates that the component size will expand to the maximum allowed by the parent component, and it will occupy the remaining size in the direction of the parent component
- Create layout in code
You need to create components and layouts respectively in SecondAbilitySlice, and organize and associate them. And we also need to set the page layout size and background color, as well as the text layout. The following code is just a brief introduction.
public class SecondAbilitySlice extends AbilitySlice { @Override public void onStart(Intent intent) { super.onStart(intent); //super.setUIContent(ResourceTable.Layout_ability_second); //1. Create layout objects DirectionalLayout dl = new DirectionalLayout(this); //2. Create a text object Text t = new Text(this); //Set content t.setText("Second page"); //Set text size t.setTextSize(55); //Set text color t.setTextColor(Color.BLUE); //3. Add the text object to the layout dl.addComponent(t); //4. Add layout to sub interface super.setUIContent(dl); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
- Code implementation page Jump
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. Find the button id btu = (Button) findComponentById(ResourceTable.Id_but1); //2. Add a click event to the button //If no click event is added, there is no response after clicking the button with the mouse. //If we add a click event to the button, the corresponding code can be executed after clicking the button with the mouse //Understanding method: //Added click event to btu this button //When we click btu this button with the mouse, we can execute the onClick method in this class btu.setClickedListener(this); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } @Override public void onClick(Component component) { //Click the button as long as the code to be executed //Jump to the second page if(component == btu){ //Only after clicking btu this button can you jump //Which page to jump to (intention) Intent i = new Intent(); //Contains the page information to jump to Operation operation = new Intent.OperationBuilder() .withDeviceId("")//The device to jump to. If you pass a string without content, it means to jump to the local machine .withBundleName("com.example.myapplication")//Which application do I want to jump to? The registration can be written in parentheses .withAbilityName("com.example.myapplication.SecondAbility")//Page to jump to .build();//Indicates that the above three information are packaged //Set the packaged operation into the intent i.setOperation(operation); //Jump page startAbility(i); } } }
The final running results are shown in the following two figures
Create a simple page layout programmatically
There has been a problem these days. We all know that the homepage of the project launch is MainAbility, and MainAbilitySlice will be loaded automatically. So here's the problem. Suppose I create another ExampleAbility (when creating the Ability, DEV will automatically help us generate the corresponding slice file, xml file in graphic and xml file in layout). How can I set the ExampleAbility as my home page?
After consulting experts, they gave two methods.
The first silly way is that we all know that the contents of MainAbility and ExampleAbility are almost the same, so we can set the route of setMainRoute to ExampleAbilitySlice in MainAbility. As shown in the figure below.
package com.example.myexampleapplication; import com.example.myexampleapplication.slice.ExampleAbilitySlice; import com.example.myexampleapplication.slice.MainAbilitySlice;//I used to use this bag. I can't use it anymore 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()); } }
I think the second method is very practical. We need to modify the contents in the config.json file. It mainly modifies the files in capabilities
"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" } ]
Which Ability we need as the first interface, we copy the contents of skills to it. As shown in the figure above, I want ExampleAbility as the first interface, so I copy the contents of skills to the corresponding array object. Finally, the Ability created programmatically is shown in the following figure
The rest of the pages haven't changed, so we just need to modify the ExampleAbilitySlice page
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 { //The three overridden methods inherit from the AbilitySlice class, which in turn inherits the AbilityContext class, which in turn inherits the Context interface //Inheritance relationship DirectionLayout inherits the ComponentContainer class, which in turn inherits the Component class, which in turn inherits the JAVA Object class @Override public void onStart(Intent intent) { //onStart and setUIContent are both from the AbilitySlice class super.onStart(intent); //super.setUIContent(ResourceTable.Layout_ability_example); //Declaration layout DirectionalLayout directionalLayout= new DirectionalLayout(getContext()); //Set layout size //The setWidth and setHeight methods inherit the parameters in the Component class and the ComponentContainer class. directionalLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT); directionalLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT); //Set layout properties //setOrientation comes from this class. Set the direction of the layout. setPadding comes from the Component to set the layout spacing. directionalLayout.setOrientation(Component.VERTICAL); directionalLayout.setPadding(32,32,32,32); //getContext comes from AbilityContext. Why can getContext be written in this place? First, we can see from the inheritance relationship that the constructor parameters in this place should be parameters of type Context //Text is the same as DirectionLayout. getContext comes from the AbilityContext class, which inherits the Context interface, so getContext can be filled in here Text text=new Text(getContext()); //setText and setTextSize are both methods from the Text class, which are well understood text.setText("Create view layout with encoding"); text.setTextSize(80); //setId is a method from the class Component, which requires extra attention. text.setId(100); //Add the layout attribute of the corresponding layout for the component, set the layout of the text, and call the construction method in DirectionLayout. This construction method can pass two parameters, which are the same as above. DirectionalLayout.LayoutConfig layoutConfig=new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT); //alignment comes from the DirectionLayout.LayoutConfig property. LayoutAlignment is the introduced class layoutConfig.alignment= LayoutAlignment.HORIZONTAL_CENTER; //setLayoutConfig from Component text.setLayoutConfig(layoutConfig); //Add Text to the layout. addComponent comes from ComponentContainer directionalLayout.addComponent(text); //Similarly, add a Button Button button=new Button(getContext()); //setMargins comes from ComponentContainer, the same as above layoutConfig.setMargins(0,50,0,0); button.setLayoutConfig(layoutConfig); button.setText("Update information"); button.setTextSize(50); //Set the background color of the page. shapeElement comes from the imported class. The construction method can not pass parameters! ShapeElement background=new ShapeElement(); //The following two methods are from the ShapeElement class. The setRgbColor constructor requires parameters of RgbColor type, so there can only be one new, from ohos.agp.colors.RgbColor; background.setRgbColor(new RgbColor(0,125,255)); background.setCornerRadius(25); //The first two are from the Component class button.setBackground(background); button.setPadding(10,10,10,10); //From the Text class, why can a button use the methods in the Text class? Button inherits the method of Text class! Pay attention to the source code! button.setTextColor(Color.WHITE); button.setClickedListener(new Component.ClickedListener() {//Click event method from Component @Override public void onClick(Component component) { System.out.println(this); } }); //addComponent comes from the ComponentContainer class directionalLayout.addComponent(button); //Adds a layout to the view tree as the root layout super.setUIContent(directionalLayout); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }