CodeNewbie Community 🌱

Cover image for ArkUI in Action: 04-A Complete Atomic Service Case
shaohushuo
shaohushuo

Posted on

ArkUI in Action: 04-A Complete Atomic Service Case

Share a complete meta-service case, which is a high imitation of Douban's mini program.

Introduction

The entire meta-service is divided into 4-5 pages, the home page is a list page, showing the current popular movies in the theater, and clicking on it is a detailed introduction page, which contains film details, cast lists, related film recommendations, etc., popular posters. Opening the poster is a complete poster display page, click on it to produce a larger picture.
Also, there is an introductory page about us.

Design

Instead of using the bottom tab, the meta service places About Us at the bottom of the page and displays it in a more euphemistic way.

Code

  1. Look at the 'entry/src/main/etc/pages/' directory, the whole app is divided into four pages. The route is configured in 'entry/src/main/resources/base/profile/main_pages.json', and the route name corresponds to the file name one-to-one. In the directory where the 'main_pages.json' is located, you can see a 'form_config.json' file, which is used to configure the service card.

Row-column layout is mostly used in the page, and various spacings are preferentially specified by 'Blank()'.

In the Album page, a grid layout is used, when you click on one of the images, a slideshow will be played, here the '@lyb/media-preview' third-party library is used, and the following is the core code:

Grid() {
    ForEach(this.items, (item: Photo, index: number) => {
      GridItem() {
        Image(item.image.normal.url)
          .width('100%')
          .height(140)
          .objectFit(ImageFit.Cover)
          .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 1.1 })
          .visibility(index == this.index ? Visibility.Hidden : Visibility.Visible)
          .onClick((event) => {
            this.options
              .setInitIndex(index)
              .setMedias(this.getPreviewResources())
              .setIndicator(false)
            MediaPreview.open(this.getUIContext(), this.options)
          })
      }
    })
  }
  .columnsTemplate('1fr 1fr 1fr')
  .columnsGap(2)
  .rowsGap(2)
  .scrollBar(BarState.Off)

Enter fullscreen mode Exit fullscreen mode
  1. The 'common' directory holds some global variables, such as the 'Constants.ets' file, which uses static variables. There is also a simple encapsulation of the request class, which also uses a static class as a singleton.

In order to make the import code more concise, and at the same time "high cohesion and low coupling", an index file is used to export the classes and methods in this directory.

The method in 'Request' uses generics, which automatically deserialize based on the type of passer, reducing the amount of boilerplate code.

  1. 'components' component directory. This is where the widgets for each package are stored. In this case, there are 4 widgets: credits, copyright notices, poster lists, and related recommendations.

'Copyright' is a simple widget that appears in the footer.

@Component
export struct Copyright {
  build() {
    Row() {
      Image($r('app.media.nutpi')).width(32)
      Blank().width(8)
      Text('εšζžœζ΄Ύε‡Ίε“').fontWeight(FontWeight.Bold).fontColor(Color.Gray)
    }.justifyContent(FlexAlign.Center)
    .width('100%')
    .onClick((event) => {
      router.pushUrl({ url: 'pages/About' })
    })
  }
}```





Enter fullscreen mode Exit fullscreen mode
  1. 'quickactions/pages/QuickActionCard.ets' is the page of the service card, which describes the UI of the card, listening for and triggering click events via Formlink

ets
 FormLink({
      action: this.ACTION_TYPE,
      abilityName: this.ABILITY_NAME,
      params: {
        action: this.MESSAGE
      }
    }) {
      Row() {
        Text('ε½±ι™’ηƒ­ζ˜ ').fontSize(14)
          .fontColor($r('app.color.card_label'))
        Image($r('app.media.icon'))
          .width(32)
      }
      .justifyContent(FlexAlign.SpaceBetween)
      .height(this.FULL_HEIGHT_PERCENT)
      .width('100%')
      .padding({
        top: 10,
        left: 12,
        right: 12,
        bottom: 10
      })
      .backgroundColor($r('app.color.background_color'))
    }


Enter fullscreen mode Exit fullscreen mode

In the code above, a row layout is described, with icons on the left and app names on the right.

  1. 'viewmodels' is the view data model. There are 5 models in this case, which are 'AppInfo', 'Celebrities', 'Movie', 'Photos', 'Relative'.

ets
export class AppInfo {
  logo: string = '';
  appName: string = '';
  appLinking: string = '';
  appId: string = '';
  desc: string = '';
  type: string = '';
}


Enter fullscreen mode Exit fullscreen mode

'AppInfo' is a simple app information class that contains information such as logo, app name, applink, description, and app type.

Miscellaneous

For more information about app creation, service cards, packaging signatures, and listing reviews, you can check past articles or the reference materials below.

Full code

The full code can be found in the repository
https://gitee.com/zacks/arkts-ohos-demo

References

HarmonyOS Native Development Notes Series:

  • [HarmonyOS Native Development Notes: 01-Meta Service Development]
  • [HarmonyOS Native Development Notes: 02-Service Card Development]
  • [HarmonyOS Native Development Notes: 01-Meta Service Development]
  • [HarmonyOS Native Development Notes: 03-Meta Service Development Process]
  • Harmony Application Packaging and Listing Process

Top comments (0)