DEV Community

陈杨
陈杨

Posted on

Hong Mong 5 development treasure case sharing three folding application development sharing

HarmonyOS Three-Foldable App Development Treasure: Official Case Study and Practical Code

Hello everyone! Today, while browsing the HarmonyOS documentation, I discovered a super valuable resource—the official three-foldable development case! I used to think multi-device adaptation was complicated, but HarmonyOS already has a comprehensive solution. Let’s get straight to the point and dive into three-foldable screen development with code examples!


🚀 Three States of the Three-Foldable and Breakpoint Adaptation

Three-foldable phones (like the Mate XT) have three core states, each corresponding to a different layout strategy:

  1. Single Screen (F State): Standard phone layout, breakpoint sm
  2. Dual Screen (M State): Similar to large foldable unfolded state, breakpoint md
  3. Triple Screen (G State): Tablet layout, breakpoint lg

Key Tip: Use breakpoints instead of device type to determine layout, ensuring code universality:

// Switch Tabs position based on breakpoint (bottom → sidebar)
@StorageLink('currentWidthBreakpoint') currentWidthBreakpoint: string = 'lg';

build() {
  Tabs({
    barPosition: this.currentWidthBreakpoint === 'lg' ? 
      BarPosition.Start : BarPosition.End // Sidebar for lg, bottom for others
  }) {
    ...
  }
  .vertical(this.currentWidthBreakpoint === 'lg') // Vertical for lg
}
Enter fullscreen mode Exit fullscreen mode

📌 Why use breakpoints?

Avoid using deviceType == 'tablet' for judgment. The G state of a three-foldable and a tablet layout should be consistent, but device types differ!


🖼️ Typical Layout Scenarios in Practice

Scenario 1: Sidebar Navigation (Dynamic Migration from F to G State)

Effect: Bottom navigation bar on small screens, switches to left sidebar on large screens (≥840vp).

Key code points:

// 1. Listen for window changes (EntryAbility.ets)
onWindowStageCreate(windowStage: window.WindowStage) {
  windowStage.getMainWindow().then((win: window.Window) => {
    win.on('windowSizeChange', (size: window.Size) => {
      AppStorage.setOrCreate('windowWidth', size.width); // Store window width
    });
  });
}

// 2. Dynamically adjust navigation bar on page (Home.ets)
@StorageProp('windowWidth') winWidth: number = 0;

build() {
  if (this.winWidth >= 840) { // Reaches lg breakpoint
    Navigation() {
      SideBar() { ... } // Left navigation
      ContentArea() { ... }
    }
  } else {
    BottomTabs() { ... } // Bottom navigation
  }
}
Enter fullscreen mode Exit fullscreen mode

Scenario 2: Waterfall Image Adaptive Columns

Problem: 2 columns on small screens, 3 columns on large screens with adjusted aspect ratio.

Code solution:

// Set WaterFlow columns based on breakpoint
@StorageLink('currentBreakpoint') breakpoint: string;

build() {
  WaterFlow() {
    ForEach(this.imageList, (item) => {
      Image(item.url)
        .aspectRatio(1.5) // Fixed aspect ratio to prevent distortion
    })
  }
  .columnsTemplate(this.breakpoint === 'lg' ? 
    '1fr 1fr 1fr' : '1fr 1fr' // 3 columns for lg, 2 for others
  )
}
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Carousel Extended Effect on Large Screens

G State Exclusive: Partially reveal content on both sides for enhanced visual extension.

Key API: prevMargin + nextMargin

Swiper() {
  ForEach(this.bannerList, (item) => {
    Image(item.url)
  })
}
.displayCount(5) // Show 5 images in G state
.prevMargin(40)  // Reveal 40px on the left
.nextMargin(40)  // Reveal 40px on the right
.itemSpace(10)    // Image spacing
Enter fullscreen mode Exit fullscreen mode

Scenario 4: Hover Camera (Special Interaction in Half-Fold State)

Effect: Trigger hover shooting mode when the screen is half-folded.

Code focus: Listen for fold state + lock landscape orientation

// Listen for fold status changes
display.on('foldStatus', (status: display.FoldStatus) => {
  if (status === display.FoldStatus.FOLD_STATUS_HALF_FOLDED) {
    this.isHalfFolded = true; // Enter hover state
    window.getLastWindow().then(win => {
      win.setPreferredOrientation(window.Orientation.LANDSCAPE); // Force landscape
    });
  }
});

// UI exclusive to hover state
build() {
  if (this.isHalfFolded) {
    SuspendedCameraView() // Hover shooting component
  }
}
Enter fullscreen mode Exit fullscreen mode

⚠️ Pitfall Guide

  1. Rotation Failure Issue Wrong approach: Use fold state to determine rotation (G state of three-foldable ≠ unfolded state of large foldable). Correct solution: Control with window aspect ratio:
// Set camera preview area based on aspect ratio
if (widthBp === 'md' && heightBp === 'md') { 
  surfaceRect = { width: winWidth, height: winWidth * 0.75 }; // 4:3 ratio
}
Enter fullscreen mode Exit fullscreen mode
  1. Layout Stretching Issue Must-add property: .aspectRatio() to ensure image/video proportions:
GridItem() {
  VideoPlayer().aspectRatio(16/9) // Force 16:9
}
Enter fullscreen mode Exit fullscreen mode

💎 Summary

The core of HarmonyOS's three-foldable adaptation solution can be summarized as:

Breakpoint-driven layout: sm/md/lg covers all states

Dynamic component properties: Tabs/WaterFlow/Swiper adjust parameters based on breakpoints

Special state listening: Hover state triggered by foldStatus

For those developing foldable screens, start using these now! If you have any questions, feel free to discuss in the comments. More hidden HarmonyOS tips coming next time! ✨

Top comments (0)