Building a Simple Notepad App with HarmonyOS Native ArkTS and ArkUI
This tutorial walks you through creating a basic HarmonyOS notepad application using the native ArkTS language and ArkUI components, covering project setup, directory structure, UI layout, routing, and implementing add‑and‑delete functionality with complete code examples.
Introduction
Hello, I am 石小石! In the previous tutorial we used a js‑style web development paradigm to create a simulated dial. In this tutorial we will use the HarmonyOS native ArkTS language to build a simple notepad application, helping you quickly get started with HarmonyOS app development.
Knowledge Review
HarmonyOS SDK
The HarmonyOS SDK is a collection of open capabilities covering six domains such as application framework, services, system, media, AI, and graphics, enabling both "meta‑service development" and "native HarmonyOS app development".
HarmonyOS Native App Development
Native HarmonyOS apps can run on phones, tablets, TVs, car screens, and wearables. To develop native apps you need three basics:
DevEco Studio – the IDE similar to IntelliJ IDEA.
ArkTS – the programming language that extends TypeScript with stricter static checking.
ArkUI – a declarative UI framework built on ArkTS, analogous to the relationship between JavaScript and Element UI.
Building the First Application
Official API documentation can be found at the HarmonyOS developer portal.
Project Creation
Click "Create Project" .
Select "Application" (choose "Atomic Service" for meta‑service development).
Templates indicate which terminals the app can run on.
Project Preview
Click the Previewer button on the right side to view the default project.
Project Directory Structure
├── .hvigor # temporary build files or config
├── .idea # IDE configuration
├── AppScope
│ └── entry # HarmonyOS module, compiled into a HAP package
│ ├── src
│ │ ├── main
│ │ │ └── ets
│ │ │ ├── entryability # app/service entry
│ │ │ │ └── [ArkTS source files]
│ │ │ └── entrybackupability # backup/restore capability
│ │ │ └── [ArkTS source files]
│ │ ├── pages # pages of the app/service
│ │ │ └── Index.ets # page source file
│ │ └── resources # resource files
│ │ └── mock
│ │ └── ohosTest
│ │ ├── test
│ │ │ └── .gitignore
│ │ ├── build-profile.json5
│ │ ├── hvigorfile.ts
│ │ ├── obfuscation-rules.txt
│ │ └── oh-package.json5
│ └── module.json5 # module config
├── .gitignore
├── build-profile.json5
├── hvigorfile.ts
├── obfuscation-rules.txt
├── oh-package.json5
└── oh_modules
├── .gitignore
├── build-profile.json5
├── hvigorfile.ts
├── local.properties
└── oh-package-lock.json5For beginners the structure can be simplified to focus on the pages folder and module.json5 for page configuration.
Code Overview
The default template contains minimal code. Below is the basic entry component:
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}Key concepts include decorators (@Entry, @Component, @State), declarative UI description, custom components, system components, and chainable property methods.
Building the First Page
Page Description
The page contains a centered button that navigates to a second page.
@Entry
@Component
struct Index {
build() {
Row() {
// Add button component
Button() {
Text('你好,鸿蒙')
.fontSize(22)
.fontColor('#fff')
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Normal)
.borderRadius('10%')
.margin({ top: 20 })
.backgroundColor('#ff9c6e')
.width('40%')
.height('5%')
.onClick(() => {
router.pushUrl({ url: 'pages/Second' })
})
}
.width('100%')
.height('100%')
.backgroundColor('#d4380d')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}Page Layout
Using Row to center the button and applying width, height, backgroundColor, alignItems, and justifyContent properties.
Navigation
Import the router module and call router.pushUrl({url: 'pages/Second'}) inside the button's onClick handler.
Building the Second Page
Create Second Page
Right‑click the pages folder, choose New > ArkTS File , name it Second , and add the following content:
@Entry
@Component
struct Second {
@State message: string = '这是第二个页面'
build() {
Row() {
Column() {
Text(this.message)
}
.width('100%')
}
.height('100%')
}
}Configure Route
Add "pages/Second" to the src array in main_pages.json under the base/profile directory.
{
"src": [
"pages/Index",
"pages/Second"
]
}Notepad Page Implementation
Page Description
The page should contain a text input, an "Add" button, and a list displaying the notes.
Basic Layout
@Entry
@Component
struct NotesPage {
@State notes: string[] = ['事项1', '事项2', '事项3'];
@State newNote: string = '';
build() {
Column() {
Text('石小石的记事本')
.fontSize(24)
.fontColor('#003eb3')
.margin({ top: 20, bottom: 20 });
TextInput({
text: this.newNote,
placeholder: '添加新的事项'
})
.width('80%')
.margin({ bottom: 10 })
.padding(10)
.fontSize(16)
.borderColor('#ccc')
.borderWidth(1)
.borderRadius(5)
.onChange((value:string) => { this.newNote = value });
Button('添加')
.onClick(() => this.addNote())
.width('80%')
.padding(10)
.fontSize(16)
.backgroundColor('#007AFF')
.fontColor('#FFF')
.borderRadius(5);
List() {
ForEach(this.notes, (item:string, index:number) => {
ListItem() {
Row() {
Text(item).fontColor('#001d66');
Button('删除')
.onClick(() => this.deleteNote(index))
.fontSize(14)
.height(18)
.backgroundColor('#ff4d4f')
.type(ButtonType.Normal)
.borderRadius('15%')
.padding({ left:10, right:10 });
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#bae0ff')
.margin({ bottom:5 })
.padding(5);
}
})
}
.width('80%')
.margin({ top:20 });
}
.width('100%')
.backgroundColor('#e6f4ff')
.height('100%');
}
addNote() {
if (this.newNote.trim() !== '') {
this.notes.push(this.newNote);
this.newNote = '';
}
}
deleteNote(index: number) {
this.notes.splice(index, 1);
}
}Full Code and Demo
Below are the complete source files for the initial page and the notepad page, demonstrating navigation, UI layout, and add/delete functionality.
// Index.ets (initial page)
import { router } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Button() {
Text('你好,鸿蒙')
.fontSize(22)
.fontColor('#fff')
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Normal)
.borderRadius('10%')
.margin({ top: 20 })
.backgroundColor('#ff9c6e')
.width('40%')
.height('5%')
.onClick(() => {
router.pushUrl({ url: 'pages/Second' })
})
}
.width('100%')
.height('100%')
.backgroundColor('#d4380d')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}
} // NotesPage.ets (notepad page)
@Entry
@Component
struct NotesPage {
@State notes: string[] = ['事项1', '事项2', '事项3'];
@State newNote: string = '';
addNote() {
if (this.newNote.trim() !== '') {
this.notes.push(this.newNote);
this.newNote = '';
}
}
deleteNote(index: number) {
this.notes.splice(index, 1);
}
build() {
Column() {
Text('石小石的记事本')
.fontSize(24)
.fontColor('#003eb3')
.margin({ top: 20, bottom: 20 });
TextInput({ text: this.newNote, placeholder: '添加新的事项' })
.onChange((value:string) => { this.newNote = value })
.width('80%')
.margin({ bottom: 10 })
.padding(10)
.fontSize(16)
.borderColor('#ccc')
.borderWidth(1)
.borderRadius(5);
Button('添加')
.onClick(() => this.addNote())
.width('80%')
.padding(10)
.fontSize(16)
.backgroundColor('#007AFF')
.fontColor('#FFF')
.borderRadius(5);
List() {
ForEach(this.notes, (item:string, index:number) => {
ListItem() {
Row() {
Text(item).fontColor('#001d66');
Button('删除')
.onClick(() => this.deleteNote(index))
.fontSize(14)
.height(18)
.backgroundColor('#ff4d4f')
.type(ButtonType.Normal)
.borderRadius('15%')
.padding({ left:10, right:10 });
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#bae0ff')
.margin({ bottom:5 })
.padding(5);
}
})
}
.width('80%')
.margin({ top:20 });
}
.width('100%')
.backgroundColor('#e6f4ff')
.height('100%');
}
}Conclusion
This tutorial demonstrates how to use native ArkTS together with ArkUI components to create a simple welcome page and a functional notepad page on HarmonyOS. It covers code structure, UI component usage, routing configuration, and basic add/delete event handling, providing a solid foundation for further HarmonyOS development.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.