DEV Community

CoderFeri
CoderFeri

Posted on

Mastering HarmonyOS NEXT Modal Pages: A Comprehensive Guide to Effortless Implementation

Mastering HarmonyOS NEXT Modal Pages: A Comprehensive Guide to Effortless Implementation

0. Preface

Recently, while working on the HarmonyOS NEXT native development of an exam app, I hit a roadblock when it came to displaying the answer sheet for the exam feature. Initially, I used pop - up windows for the answer sheet, but the result was a far cry from expectationsβ€”it was so poorly presented that I almost considered resigning out of embarrassment (just kidding). After some reflection, I discovered the "magic weapon" of modal pages, which opened up a whole new world for me. Today, I'd like to share with you how to work with these amazing features.

1. Modal Pages: The "Transformers" of Pop - up Windows πŸ€–

Imagine you're playing a game, and suddenly a task panel (modal page) pops up. It doesn't block the game screen but allows you to focus on handling the taskβ€”that's the charm of modal pages.
It's a "large - panel interactive pop - up window." The biggest difference from regular pop - up windows is that the content is fully customizable, so you can include as much information as you need (such as your exam answer sheet). ArkUI offers two forms:

Semi - modal: A non - full - screen pop - up that allows the underlying page to be partially visible. It's suitable for lightweight operations, like selecting a date or filling in a note.
Full - modal: A domineering full - screen overlay that can only be dismissed by swiping from the side. It's ideal for scenarios that require immersive operations, such as viewing an extra - long answer sheet.

Key point: The semi - modal can be dismissed by swiping, tapping the dimmed background, or clicking the close button. The full - modal, by default, can only be dismissed by swiping, effectively preventing accidental touches by clumsy users!

2. Semi - modal Pages: The Gentle "Side Assistant" πŸ‘¨πŸ’»

Semi - modal pages are like your attentive personal assistants. They don't block the main interface but help you complete tasks quickly. For example, when implementing a "memorial day management" feature, you can select a date and write a note seamlessly.
Lifecycle: The "Heartbeat Record" of the Pop - up πŸ“…
The life cycle of a semi - modal is straightforward:
Before birth (onWillAppear) β†’ Debut (onAppear) β†’ Before disappearance (onWillDisappear) β†’ Exit (onDisappear)
Just like an actor on stage, each stage has its own corresponding "background music" (callback functions), allowing you to "control" its state at any time.
Code Implementation: Step - by - Step Guide to Building a "Memorial Day Assistant" πŸš€

@Entry
@Component
struct Index {
  // Define the state of whether the page is displayed (it's just like a switch)
  @State isShow:boolean=false;
  // Selected date: set to today by default to prevent users from choosing magical options like "tomorrow's exam"
  @State selectedDate:Date=new Date();
  // Remark information: left blank for users to fill in
  @State remark:string="";

  // Method to create a semi - modal page: it's like building with blocks, stacking components together
  @Builder
  createSheet() {
    Column({ space: 10 }) { // Column layout, components arranged vertically with a 10px gap
      Row({ space: 10 }) { // Row layout, components arranged horizontally with a 10px gap
        Text("Memorial Day:") // Label to tell users this is for date selection
        // Calendar picker: aligned to the right, with a striking red font color, and allows date selection on click
        CalendarPicker({ hintRadius: 10, selected: this.selectedDate })
          .edgeAlign(CalendarAlign.END)
          .textStyle({ color: "#ff182431", font: { size: 20, weight: FontWeight.Normal } })
          .margin(10)
          .onChange((value) => { // Log the selected date for easy debugging
            console.info("CalendarPicker onChange:" + JSON.stringify(value))
          })
      }
      .margin({ top: 30 }) // 30px top margin to separate from the component above
      .width("90%") // Width takes up 90% of the parent container to avoid overflowing the screen

      Row() { // Remark input box area
        Text("Remark:") // Label
        TextInput({ placeholder: "Please enter remark information" }) // Input box, prompting the user to "write something"
          .onChange(v => { // Update the remark variable in real - time as the user types
            this.remark = v
          })
      }
      .width("90%") // Also takes up 90% width

      // Confirm and save button: shows a Toast when clicked and closes the pop - up
      Button("Confirm and Save")
        .width("80%") // Make the button a bit narrower for a more refined look
        .onClick(() => {
          this.getUIContext().getPromptAction().showToast({
            message: "Memorial Day: " + this.selectedDate.toDateString() + " Remark: " + this.remark
          })
          this.isShow = false; // Close the pop - up, and peace is restored
        })
    }
    .width("90%") // The entire semi - modal content area takes up 90% width
    .padding(20) // 20px internal padding to prevent components from being cramped
  }

  // Main page layout: a button to open the semi - modal
  build() {
    Column({space:20}){
      Text("Semi - modal Page") // Title, simple and straightforward
      Button("Open Semi - modal Page") // Button, clicks to trigger the "switch"
        .bindSheet($$this.isShow,this.createSheet,
          {mode:SheetMode.EMBEDDED, detents: [SheetSize.MEDIUM, SheetSize.LARGE, 300]})
        .onClick(()=>{ // Set the "switch" to on (isShow to true) when clicked
          this.isShow=true;
        })
    }
    .height('100%') // Fill the screen height
    .width('100%') // Fill the screen width
  }
}
Enter fullscreen mode Exit fullscreen mode

Effect Preview: The Transformation from "Ugly Duckling" to "Swan" πŸ“±
Before opening: The main page is clean, with only an "Open" button, like an unopened parcel.
After opening: The semi - modal slides up from the bottom, bringing the calendar and input box, like a "secret drawer" popping out.
During operation: Slide to select the date, enter the remark. The underlying page is dimmed but still visible, constantly reminding you "I'm still here."
When closing: Swipe, tap the dimmed background, or click the button, and the pop - up smoothly disappears, as if nothing happened (but the data has been saved, of course).
Conclusion: Why Are Modal Pages So Great? πŸ€”
High flexibility: Easily switch between semi - modal and full - modal to adapt to different scenarios (use full - modal for exam answer sheets and semi - modal for date selection).
User - friendly experience: Don't block the main interface, and the operation logic is intuitive (swiping to close is extremely convenient).
Highly customizable: You can write everything from the layout to the interaction, so you can make it as cool as you want (for example, add a sliding page - turning effect to the answer sheet).

Next time, I plan to talk about practical cases of full - modal pages, such as how to use them to create an "immersive exam answer sheet." If you encounter any strange problems during development, feel free to leave a comment, and let's figure them out together! πŸ’ͺ

Where there is a will, there is a way! I'm Feri, an experienced programmer dedicated to the growth of fellow developers. See you next time! πŸš—πŸ’¨

Top comments (0)