Multi-Device Scenario Library

Overview

The multi-device library (multidevicelibrary) is a common HAR library that provides scenario-based window orientation management and adaptive layout features for multi-device applications. The library contains four core modules:

  • Scene management: uses SceneController to push and release scenes when a page enters or exits, and automatically recalculate and apply the orientation configuration of the stack top scene.
  • Window orientation control: provides three orientation strategies: fixed, autoRotate, and followDesktop, and encapsulates the reading, application, and restoration of window orientations.
  • Responsive rule engine: a rule evaluator based on conditions (field/operator/value) that, together with the custom context, dynamically selects orientation configurations based on the device form.
  • Adaptive layout for short videos: provides the AdaptiveShortVideoScene (scenario container) and AdaptiveVideoSurface (adaptive rendering container), which support two-layer parsing of RegionMode and FitMode to implement adaptive scaling and immersive experience for short videos.

The library provides preset scenarios and orientation configurations for 20 page types (PageType), which are ready to use out of the box.

Preview

This library is a code library and does not have an independent running UI. Its capabilities are demonstrated through the multi-device scenario examples of the main project (such as the application home page, landscape/portrait game, gallery, individual stock details/K-line chart, long video details/full-screen playback, and short video playback). For details, see the README file of the main project.

How to Use

  1. Add the dependency "multidevicelibrary": "file:../../commons/multidevicelibrary" to the oh-package.json5 file of the module.
  2. In EntryAbility, create a custom context (ResponsiveContext), an OrientationController (to bind the window and context), and a SceneController (to bind the OrientationController), and store the SceneController in AppStorage.
  3. Listen for window size changes (windowSizeChange) and screen attribute changes (display 'change'). In the callback, update the ResponsiveContext and call scene.recompute() to re-parse the orientation.
  4. Call scene.push(ScenePresets.XXX) in aboutToAppear to push the scene, and call scene.release(layerId) in aboutToDisappear to release the scene.
  5. Use adaptive layout for short videos:
    • Use the scene container AdaptiveShortVideoScene to wrap the short video content area and pass the overlayTop and overlayBottom (height of the top status bar and bottom tab) parameters. The component automatically pushes or releases the SHORT_VIDEO scene.
    • Use the adaptive rendering container AdaptiveVideoSurface to wrap the video player and pass the videoWidth and videoHeight (original width and height of the video) parameters. AdaptiveVideoSurface will automatically calculate and apply the final width, height, and offset of the video.

Project Directory

├──Index.ets                                 // Library export entry
└──src/main/ets
   ├──context                                // Context
   │  ├──DefaultContext.ets                  // Context API
   │  └──ContextTypes.ets                    // API definition
   ├──hover                                  // Hover state monitoring
   │  ├──HoverDataStore.ets                  // Hover state monitoring implementation
   │  └──HoverProvider.ets                   // Hover state context implementation
   ├──orientation                            // Window orientation control
   │  ├──OrientationConfig.ets               // Orientation configuration type (Fixed/AutoRotate/FollowDesktop)
   │  ├──OrientationController.ets           // Window orientation application controller
   │  ├──OrientationStrategy.ets             // Mapping from the orientation strategy to the window orientation
   │  └──presets
   │     └──ResponsiveOrientationConfig.ets  // Preset orientation configuration by page type (PageType)
   ├──responsiverule                         // Responsive rule engine
   │  ├──ConditionValue.ets                  // Condition value type
   │  ├──ResponsiveValue.ets                 // Alias of the responsive value type
   │  ├──ResponsiveValueResolver.ets         // Rule parser
   │  └──condition
   │     ├──Condition.ets                    // Condition API
   │     ├──ConditionResponsiveValue.ets     // Condition responsive value API
   │     ├──Operator.ets                     // Operator enumeration
   │     ├──OperatorPredicates.ets           // Operator predicate implementation
   │     └──ConditionRule.ets                // Rule API
   ├──scene                                  // Scene management
   │  ├──Scene.ets                           // Scene API
   │  ├──SceneController.ets                 // Scene stack controller
   │  ├──presets
   │  │  └──ScenePresets.ets                 // Preset scene set
   │  └──shortvideo                          // Adaptive layout preset for short videos
   │     ├──component
   │     │  ├──AdaptiveShortVideoScene.ets   // Scene container
   │     │  └──AdaptiveVideoSurface.ets      // Adaptive rendering container
   │     ├──material
   │     │  ├──ShortVideoRule.ets            // Responsive rule definition
   │     │  └──ShortVideoTypes.ets           // Type definition
   │     └──runtime
   │        ├──FitModeResolver.ets           // Adaptive mode resolver
   │        └──RegionResolver.ets            // Region mode resolver
   └──AbilityRegister.ets                    // Context registration

How to Implement

  1. Scene stack management: SceneController maintains a SceneLayer stack. When a scene is pushed, it is added to the stack and recompute is triggered. When a scene is released, it is removed from the stack based on the layer ID and recompute is triggered. recompute traverses the stack from bottom to top, selects the highest non-empty orientation configuration, and applies it through OrientationController. When the stack is empty, the entry orientation snapshot is restored.
  2. Orientation strategy mapping: OrientationStrategy maps OrientationConfig to window.Orientation. followDesktop returns FOLLOW_DESKTOP; fixed locks based on the direction type; autoRotate returns the restricted auto-rotation or user rotation direction based on the range.
  3. Responsive rule evaluation: ResponsiveValueResolver considers the developer's context as Record<string, ConditionValue>, traverses each condition of the rule, and uses the predicate in OperatorPredicates to determine whether the field value meets the condition. The value of the first rule that matches all conditions takes effect. Otherwise, the default value is returned.
  4. Preset configuration: ResponsiveOrientationConfig returns the corresponding orientation configuration based on the PageType. ScenePresets provides a preset scene for each page type.
  5. Adaptive layout for short videos: A two-layer parsing model is used. Region mode (RegionMode): It is parsed by RegionResolver to determine the overall layout of the video region. Fit mode (FitMode): It is parsed by FitModeResolver based on the original aspect ratio of the video and the aspect ratio of the region to determine the scaling mode of the video in the region.
  6. Hover state detection: The system hover state and the current direction of the crease area are monitored to calculate the hover state variable isHover.

Required Permissions

None

Constraints

  1. This sample is only supported on bar phones, bi-fold devices (Mate X series), tri-fold devices, tablets, PCs, telematic devices, and Huawei Vision running standard systems.
  2. The HarmonyOS version must be HarmonyOS 6.1.0 Release or later.
  3. The DevEco Studio version must be DevEco Studio 6.1.0 Release or later.
  4. The HarmonyOS SDK version must be HarmonyOS 6.1.0 Release SDK or later.