Hongmeng App development HarmonyOS: network request + third-party library use + bottom bar switching + list + Banner

The general content of this article is as follows:

  1. Show results
  2. Breakdown of knowledge points
  3. Implementation
  4. Final summary

1. Effect display

2. Breakdown of knowledge points

1. Use of basic components

  • Tabs + TabContent

Based on the Tabs component, there are two TABs showing the "Home" TAB and the "Project" TAB respectively. In this example, there is no content under the project TAB. It is only used to display the Tabs component.

Tabs is a container component that switches content views through tabs. Each tab corresponds to a content view. It needs to be used with the TabContent component. TabContent is only used in Tabs and corresponds to a content view for switching tabs.

  • Swiper

The Swiper component placed at the top of the homepage, a slider view container, provides the ability to display a sliding carousel of sub-components.

  • Web

Provides web components with web page display capabilities, and @ohos.web.webview provides web control capabilities.

2. Page jump

@system.router (page routing) access different pages through different uri.

In this example, after clicking the Swiper component content or article list item, you will jump to the web page in the application.

3. Network request

@ohos.net.http (data request)

Referring to Hongmeng's official sample code, the http data request is simply encapsulated. You can send get type requests.

4. Introduce third-party libraries

Since Hongmeng's native List control does not have pull-down refresh and pull-up loading functions, and the demo supporting pull-down refresh and pull-up loading provided on the developer's official website is not convenient to use. Therefore, a third-party library is used in this example. The introduced third-party library will be much more convenient when implementing list pull-down and pull-up operations.

This is also an important feature of third-party libraries that can speed up app development. In this example, the third-party list library is introduced to demonstrate how to introduce a static third-party library into Hongmeng development.

3. Specific implementation

First, you need to establish the homepage structure. Add the Tabs component to MainPage and add TabContent to Tabs.

@Builder TabBuilder(title: string, index: number, icon: Resource) {
  Column() {
    Image(icon)
      .width($r('app.float.mainPage_baseTab_size'))
      .height($r('app.float.mainPage_baseTab_size'))
      .fillColor(this.getTabBarColor(index))
    Text(title)
      .margin({ top: $r('app.float.mainPage_baseTab_top') })
      .fontSize($r('app.float.main_tab_fontSize'))
      .fontColor(this.getTabBarColor(index))
  }
  .justifyContent(FlexAlign.Center)
  .height($r('app.float.mainPage_barHeight'))
  .width(Constants.FULL_PARENT)
  .onClick(() => {
    this.currentTabIndex = index;
    this.tabsController.changeIndex(this.currentTabIndex)
  })
}

build() {
  Tabs({
    barPosition: BarPosition.End,
    controller: this.tabsController
  }) {
    // 首页
    TabContent() {
      Home()
    }
    .padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
    .backgroundColor($r('app.color.mainPage_backgroundColor'))
    .tabBar(this.TabBuilder(Constants.HOME_TITLE, Constants.HOME_TAB_INDEX
      , $r('app.media.ic_bottom_home')))

    // 项目
    TabContent() {
      Project()
    }
    .padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
    .backgroundColor($r('app.color.mainPage_backgroundColor'))
    .tabBar(this.TabBuilder(Constants.PROJECT_TITLE, Constants.PROJECT_TAB_INDEX
      , $r('app.media.ic_bottom_project')))
  }
  .width(Constants.FULL_PARENT)
  .backgroundColor(Color.White)
  .barHeight($r('app.float.mainPage_barHeight'))
  .barMode(BarMode.Fixed)
  .onChange((index: number) => {
    this.currentTabIndex = index;
  })
}

Home consists of a Banner custom component and an ArticleList custom component

@Component
export default struct Home {
  build() {
    Stack() {
      ArticleList();
      Banner();
    }.alignContent(Alignment.Top)
  }
}

Banner data is requested in the Banner component and filled in the Swiper component.

The request is sent during the aboutToAppear life cycle.

For components, aboutToAppear and aboutToDisappear are commonly used during the development process.

aboutToAppear

aboutToAppear?(): void

The aboutToAppear function is executed after creating a new instance of the custom component but before executing its build function. Allows changing state variables in the aboutToAppear function, and the changes will take effect in subsequent executions of the build function.

aboutToDisappear

aboutToDisappear?(): void

The aboutToDisappear function is executed before the custom component is destructed and destroyed. Changing state variables in the aboutToDisappear function is not allowed, especially modification of @Link variables may cause unstable application behavior.

When you click on the Banner item, the page will jump.

aboutToAppear() {
  HomeViewModel.getHomeBanner(Constants.GET_HOME_BANNER).then((data: HomeBannerItemBean[]) => {
    this.bannerData = data;
  }).catch((err: string | Resource) => {
    promptAction.showToast({
      message: err,
      duration: Constants.ANIMATION_DURATION
    });
  });
}

build() {
  Column() {
    Swiper(this.swiperController) {
      ForEach(this.bannerData, (banner: HomeBannerItemBean) => {
        Image(banner.imagePath).borderRadius($r('app.float.home_swiper_borderRadius')).onClick(() => {
          router.pushUrl({
            url: 'pages/WebPage',
            params: {
              title: banner.title,
              src: banner.url
            }
          }, router.RouterMode.Single)
        })
      }, (img: Resource) => JSON.stringify(img.id))
    }
    .margin({top: $r('app.float.home_swiper_margin')})
    .autoPlay(true)
    .width(Constants.FULL_PARENT)
    .height($r('app.float.main_swiper_height'))
  }
}

The article list is implemented and data requests are also made in aboutToAppear. You can see that the third-party component ListView used here easily achieves the target function.

aboutToAppear() {
  this.getHomeArticleList(true);
}

@Builder
itemLayout(item, index) {
  ArticleItem({articleData: item})
}

getHomeArticleList(reset: boolean) {
  HomeViewModel.getHomeArticleList(this.currentPage, this.pageSize, Constants.GET_HOME_ARTICLE_LIST)
    .then((data: ArticleDataBean) => {
    if (data.curPage < data.pageCount) {
      this.currentPage++;
      this.hasMore = true;
    }  else {
      this.hasMore = false;
    }
    if (reset) {
      this.articleData = data.datas;
    } else {
      this.articleData = this.articleData.concat(data.datas);
    }
  }).catch((err: string | Resource) => {
    promptAction.showToast({ message: err});
  })
}

build() {
  ListView({
    items: this.articleData, //数据源 数组
    itemLayout: (item, index) => this.itemLayout(item, index),
    controller: this.controller, //控制器,负责关闭下拉和上拉
    marginHeader: 160,
    onRefresh: () => {
      //下拉刷新
      this.getHomeArticleList(true);
      this.controller.finishRefresh()
    },
    onLoadMore: () => {
      //上拉加载
      this.getHomeArticleList(false);
      this.controller.finishLoadMore()
    }
  })
}

Create a new WebPage to encapsulate Web components to display web pages. WebPage accepts the src parameter as the page URL and the title parameter as the title bar text.

import router from '@ohos.router';
import web_webview from '@ohos.web.webview'
import Constants from '../common/Constants';

@Entry
@Component
struct WebPage {
  @State src: string = router.getParams()?.['src'];
  @State title: string = router.getParams()?.['title'];

  controller: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      PageTitle({ titleName: this.title })

      Divider()
        .strokeWidth('1px')
        .color($r('sys.color.ohos_id_color_list_separator'))

      Web({
        src: this.src, controller: this.controller
      }).javaScriptAccess(true)
    }
  }
}

@Component
struct PageTitle {
  private titleName: string

  build() {
    Row() {
      Image($r('app.media.back'))
        .width(20)
        .height(20)
        .onClick(() => {
          router.back()
        })
      Text(this.titleName)
        .fontSize(Constants.PAGE_TITLE_TEXT_SIZE)
        .width(Constants.PAGE_TITLE_TEXT_WIDTH)
        .maxLines(Constants.PAGE_TITLE_TEXT_MAX_LINES)
        .textOverflow({overflow: TextOverflow.Ellipsis})
        .margin({ left: 20 })
    }
    .padding(12)
    .width('100%')
  }
}

Don't forget to add the WebPage page in the pages configuration

This configuration is located in ets/resources/base/profile/main_pages.json

{
  "src": [
    "pages/MainPage",
    "pages/WebPage"
  ]
}

The network request method is encapsulated. In actual projects, you can consider replacing it with other third-party libraries to implement network requests. To implement header interception, error interception and other operations, as well as other common requirements such as post types.

The open interfaces used in this example come from the selfless dedication of WanAndroid. Only 2 interfaces are used in this example. If you are interested, you can refer to it and implement all interfaces by yourself.

Thanks to Mr. Hongyang’s WanAndroid website for providing the portal.

/**
 * Initiates an HTTP request to a given URL.
 *
 * @param url URL for initiating an HTTP request.
 * @param params Params for initiating an HTTP request.
 */
export function httpRequestGet(url: string): Promise<ResponseResult> {
  let httpRequest = http.createHttp();
  let responseResult = httpRequest.request(url, {
    method: http.RequestMethod.GET,
    readTimeout: Constants.HTTP_READ_TIMEOUT,
    header: {
      'Content-Type': ContentType.JSON
    },
    connectTimeout: Constants.HTTP_READ_TIMEOUT,
    extraData: {}
  });
  let serverData: ResponseResult = new ResponseResult();
  // Processes the data and returns.
  return responseResult.then((value: http.HttpResponse) => {
    if (value.responseCode === Constants.HTTP_CODE_200) {
      // Obtains the returned data.
      let result = `${value.result}`;
      let resultJson: ResponseResult = JSON.parse(result);
      if (resultJson.errorCode === Constants.SERVER_CODE_SUCCESS) {
        serverData.data = resultJson.data;
      }
      serverData.errorCode = resultJson.errorCode;
      serverData.errorMsg = resultJson.errorMsg;
    } else {
      serverData.errorMsg = `${$r('app.string.http_error_message')}&${value.responseCode}`;
    }
    return serverData;
  }).catch(() => {
    serverData.errorMsg = $r('app.string.http_error_message');
    return serverData;
  })
}

Introducing the introduction method of third-party libraries:

Currently, you can use the method of downloading the static package and copying it to the project to implement the introduction of third-party libraries. First, create a new folder in the entry directory, such as libs. Copy the downloaded har package into it. Then open the oh-package.json5 file in the entry directory. Fill in the address of the imported har package in the dependencies field.

After completion, perform a sync operation. The introduced third-party static packages will be added to the project in code form.

4. Final summary

Hongmeng basic UI component usage + page jump + network data request + third-party component introduction. This set of basic operations is essential when starting to write an App. Once you are proficient, you can continue to explore Hongmeng Development. It’s a bit rough at the beginning, so please bear with me!

In order to allow everyone to better learn the development technology of Harmony OS, we have specially compiled the "Harmony OS Development Learning Manual" (890 pages in total). I hope it will be helpful to everyone:https://qr21.cn/FV7h05

"Harmony OS Development Learning Manual"

Must-see for getting started:https://qr21.cn/FV7h05

  1. Application Development Guide (ArkTS)
  2. Introduction to Application Development (Java)

HarmonyOS concept:https://qr21.cn/FV7h05

  1. system definition
  2. Technology Architecture
  3. Technical characteristics
  4. system security

How to get started quickly:https://qr21.cn/FV7h05

  1. basic concept
  2. Building your first ArkTS application
  3. Build your first JS application
  4. ……

Development basics:https://qr21.cn/FV7h05

  1. Application basics
  2. Configuration file
  3. Application data management
  4. Application security management
  5. App privacy protection
  6. Third-party application call control mechanism
  7. Resource classification and access
  8. Learn the ArkTS language
  9. ……

Developed based on ArkTS:https://qr21.cn/FV7h05

  1. Ability development
  2. UI opening
  3. Public events and notifications
  4. window management
  5. media
  6. Safety
  7. Networks and Links
  8. phone service
  9. Data management
  10. Background Task Management
  11. Device management
  12. Equipment usage information statistics
  13. DFX
  14. international development
  15. Folding screen series
  16. ……

Guess you like

Origin blog.csdn.net/maniuT/article/details/134770378