This topic uses travel booking apps as a typical example to detail how the feature of one-time development for multi-device deployment is applied in actual development. The following describes how to develop 11 typical pages (the home page and pages for time selection, ticket query, ticket information filling, order submission, etc.) by complying with Differentiation, Consistency, Flexibility, and Compatibility principles of multiple devices. This enables you to quickly and efficiently master the capabilities of one-time development for multi-device deployment and implement features related to travel booking apps.
There are unique designs for core features of travel booking apps in vertical markets:
Currently, the following device types are supported: bar-type phones, bi-fold phones (Mate X series), and tablets. The following practices will focus on these product forms and provide reference examples from the perspectives of UX design, architecture design, and page development, helping you develop travel booking apps.
Before reading this topic, you need to be familiar with the ArkUI framework and the capabilities of one-time development for multi-device deployment for page development. The following sections describe how to use them in app development.
For multi-device responsive design guide for travel and accommodation apps, see Travel and Accommodation Applications.
The HarmonyOS project architecture uses a tiered architecture encompassing three layers: product customization layer, basic feature layer, and common capability layer. It provides a clear, efficient, and scalable design architecture. For details, see the logical design in Layered Architecture Design.
This section describes how to use layout capabilities in travel booking apps to adapt a set of code to multiple devices at the page level. The following describes the layout capabilities used by each page area, helping you develop travel booking apps from scratch.
The home page provides a ticket purchase window to meet users' requirements for booking tickets and reserving hotels.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Bottom/Side bar | The grid is used to listen for breakpoint changes and change the position. |
2 | Top component | The Blank component is added between the Select and TextInput components to implement the stretching capability. |
3 | Train ticket selection | The Tabs component is used to implement the stretching capability. |
4 | Access path | The displayCount attribute at different breakpoints of the Swiper component is set to implement the extension capability of the adaptive layout. |
5 | Popular news | The grid of the responsive layout and the Stack and Grid components are used. The aspectRatio attribute is set to implement the scaling capability. |
6 | Hotel booking | The grid layout of the responsive layout and the Stack and Grid components are used. The aspectRatio attribute is set to implement the scaling capability. |
The time selection page provides a calendar and timetable to help users quickly determine the travel date and filter a ticket on the corresponding date.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Date | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
The ticket query page is used to filter tickets by date and departure station, and sort tickets by departure time, price, and total duration.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Date selection | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
3 | Ticket list | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
4 | Access path | The List component is used to implement the extension capability. |
The motion effect of swiping up to query tickets is mainly used to hide some filtered information when the user swipes up, so that the user can obtain more information in immersive browsing.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Ticket list | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
The ticket information filling page provides the features of confirming orders and selecting passengers to facilitate ticket booking.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Date bar | The stretching capability is used to adaptively stretch the date and button. |
3 | Train ticket information | The grid breakpoint capability is used to implement the stretching capability on the train ticket information area at different breakpoints. |
4 | Passenger selection | The stretching capability is used to adaptively stretch the passenger selection widget. |
5 | Terms | The grid breakpoint capability is used to implement the orientation layout on the terms area at different breakpoints. |
6 | Submission button | The grid breakpoint capability is used to implement the orientation layout on the submission button at different breakpoints. |
The order submission page mainly displays ticket and passenger information, helping users confirm order information.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Date bar | The stretching capability is used to adaptively stretch the date and button. |
3 | Ticket and passenger information | The stretching capability is used to adaptively stretch the module. |
4 | Terms | The grid breakpoint capability is used to implement the orientation layout on the terms area at different breakpoints. |
5 | Submission button | The grid breakpoint capability is used to implement the orientation layout on the submission button at different breakpoints. |
The order information page displays the order details and ticket information for users to check.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Train ticket order information | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
3 | Order information widget | The Tabs component is used to implement the stretching capability. |
4 | Services | The Grid component works with the Swiper component to implement the extension and equalization capabilities. |
5 | Bottom/Side navigation | The grid breakpoint capability is used. The BarPosition attribute of the Tabs component is set at different breakpoints. |
The paid order information page allows users to view paid orders and confirm order information.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Order type selection | The Tabs component is used to implement the stretching capability. |
3 | Order information list | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
The hotel home page provides hotel reservation services.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Widget banner | The Swiper component is used for its implementation and the displayCount attribute is set to auto. |
3 | Hotel recommendation | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
4 | Bottom/Side navigation | The grid breakpoint capability is used. The BarPosition attribute of the Tabs component is set at different breakpoints. |
The hotel ranking page displays the ranking of hotels for users to select.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Hotel type selection | The Tabs component is used to implement the stretching capability. |
3 | Hotel ranking | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
The hotel details page provides detailed information about the hotel, including preview images, room types, and prices, facilitating room selection and reservation for users.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Hotel widget | The GridRow component is used to implement the orientation layout. |
3 | Room reservation discount | The stretching capability is used to adaptively stretch the text and button. |
4 | Room details | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
The effect of the top banner varies with the device type. The motion effect of sliding up the top banner and expanding the image is supported on smartphones. Foldable phones support the Scroll component to display small images. After you tap them, large images are displayed. Tablets support the Swiper component for switching between views.
The onReachStart and onWillScroll attributes of the Scroll component are used when a user swipes up to expand or swipes down to collapse the banner.
Scroll(this.scroller) {
HotelDetailsPictureView({ topLength: this.topLength })
}
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
.onReachStart(() => {
if (!this.isInitialization) {
this.topLength = 225;
this.isInitialization = true;
} else {
this.topLength = 460;
}
})
.onWillScroll((xOffset: number, yOffset: number)=>{
if (yOffset > 0) {
this.topLength = 225;
}
}) The Scroll component is used to support scrolling on a foldable phone. When a small image is tapped, the index value is passed as a parameter to change the content of the large image.
Scroll() {
Row() {
ForEach(CommonConstants.HOTEL_PICTURE_MESSAGE, (item: Resource, index: number) => {
Column() {
Image(item)
.width(CommonConstants.THIRTY_PERCENT)
.borderRadius($r('app.float.hotel_grade_border'))
.margin(index === CommonConstants.NUMBER_FOUR ? {} : { right: CommonConstants.FIVE_PERCENT })
.onClick(() => {
this.getMainPicture(index);
})
}
}, (item: Resource) => JSON.stringify(item))
}
}
.scrollBar(BarState.Off)
.margin({ top: $r('app.float.calendar_column_margin') })
.width(CommonConstants.NINETY_PERCENT)
.scrollable(ScrollDirection.Horizontal) getMainPicture(index: number) {
this.mainPictureResource = CommonConstants.HOTEL_PICTURE_MESSAGE[index];
} The Swiper component is used for tablets to scroll views.
Swiper() {
ForEach(CommonConstants.HOTEL_PICTURE_MESSAGE, (item: Resource) => {
Image(item)
.width('100')
}, (item: Resource) => JSON.stringify(item))
}
.width('40%')
.height('100%') The low price calendar page allows users to locate the most affordable time slots for booking a hotel room.
Item | sm | md | lg |
|---|---|---|---|
Final effect |
|
|
|
No. | Area | Implementation |
|---|---|---|
1 | Top component | The grid breakpoint capability is used to implement the stretching capability on the top component at different breakpoints. |
2 | Date | The List component is used to implement the extension capability, and the layoutWeight component is used to implement the stretching capability. |
Breakpoint changes are listened based on the grid layout and response effects varies with breakpoints.
getFoldStatus() {
if (this.isShowingCalendar) {
this.dialogController.open();
} else {
this.dialogController.close()
}
} Column() {
Image($r("app.media.cheap_day"))
.width('15vp')
Text(CommonConstants.ROOM_BUTTON_MESSAGES[5])
.font({ size: '8fp', weight: 500 })
.opacity(0.4)
}
.onClick(() => {
if (this.breakPoint === 'sm') {
this.pageInfos.pushPath(new NavPathInfo('LowPriceCalendarPage',[]));
} else {
this.isShowingCalendar = true;
}
})