DEV Community

SameX
SameX

Posted on

News and Information Application Adapted to All Ends in HarmonyOS Next

This article aims to deeply explore the technical details of Huawei's HarmonyOS Next system and summarize them based on practical development practices. It mainly serves as a carrier for technical sharing and communication. Errors and omissions are inevitable, and colleagues are welcome to put forward valuable opinions and questions so that we can make progress together. This article is original content, and any form of reprinting must indicate the source and the original author.

In the ecosystem of HarmonyOS Next, creating a news and information application that is adapted to all ends and provides users with a consistent and high-quality reading experience is the pursuit of many developers. Next, we will thoroughly analyze the key technologies and design ideas involved in achieving this goal.

Architectural Design for Multi-terminal Adaptation

Common UI Structures of News Applications

Common UI structures of news applications include list style, card style, and grid style. The list-style structure is simple and clear, suitable for displaying a large number of news headlines, allowing users to quickly browse the news topics. The card-style structure presents each news item in the form of a card, including information such as pictures, titles, and summaries, with a rich visual effect that can attract users' attention. The grid-style structure is often used to display multiple news items with small pictures, which can make full use of the screen space and is suitable for displaying rich information content on large-screen devices.

How HarmonyOS Next Responds to the Differential Layouts of Mobile Phones, Tablets, and PCs

  1. Mobile Phones: Mobile phone screens are relatively small, and simplicity and convenient operation are emphasized. A single-column layout is mainly adopted, and the news content is displayed in a card-style UI structure, making it convenient for users to scroll and browse with one hand. Use an adaptive layout so that the height and width of the card can be automatically adjusted according to the screen size of the mobile phone to ensure that the text and pictures are completely displayed.
  2. Tablets: Tablets have larger screens, and a dual-column or multi-column layout can be adopted to balance the amount of information displayed and the convenience of operation. Combine responsive layouts to switch the layout structure under different breakpoints. For example, when the screen is relatively narrow, a single-column card-style layout similar to that of a mobile phone is adopted, and when the screen becomes wider, it is switched to a dual-column card layout to improve the efficiency of information display.
  3. PCs: PC screens are even larger, and a more complex layout can be adopted. Usually, a three-column mode is used, with the navigation bar on the left, the information list in the middle, and the article details on the right. Use the grid layout system to precisely control the width and proportion of each column to achieve efficient information display and operation processes.

Using Adaptive Layout to Achieve UI Changes within a Single Screen

In news and information applications, adaptive layouts are used to automatically adjust the UI elements within a single screen. For example, on the news details page, the layout of pictures and text can be automatically adjusted according to the screen width. By setting the flexGrow and flexShrink properties of the Flex layout, when the screen becomes wider, the picture and text areas can be stretched proportionally; when the screen becomes narrower, the text and pictures will automatically adjust in size to avoid blank spaces or crowded situations.

@Entry
@Component
struct NewsDetailPage {
    @State articleImage: Resource = $r('app.media.newsImage')
    @State articleContent: string = 'This is the detailed content of a news article...'
    build() {
        Flex({ direction: FlexDirection.Row }) {
            Image(this.articleImage).width(200).height(150).objectFit(ImageFit.Contain).flexGrow(0).flexShrink(1)
            Column() {
                Text('News Title').fontSize(20).fontWeight(500)
                Text(this.articleContent).fontSize(14).opacity(0.8)
            }
              .flexGrow(1).flexShrink(1).paddingStart(10)
        }
          .width('100%').height('100%')
    }
}
Enter fullscreen mode Exit fullscreen mode

Implementing a News Reading Interface across Devices

To implement a news reading interface across devices, it is necessary to combine adaptive and responsive layouts. On different devices, adjust the display mode of news content according to the screen size and layout structure. On mobile phones, the news list is vertically arranged in the form of cards; on tablets and PCs, adjust it to a dual-column or multi-column card layout according to the screen width. At the same time, ensure that the news details page can provide a good reading experience on different devices, with clear text layout and normal picture display.

Listening to Breakpoints to Implement the Three-column Mode (Navigation Bar + Information List + Article Details) on Large-screen Devices

On large-screen devices (such as PCs and some tablets), the three-column mode is implemented by listening to breakpoints. Use the GridRow and GridCol components in combination with breakpoint configurations to achieve the switch of different layouts.

@Entry
@Component
struct BigScreenNewsLayout {
    @State currentBreakpoint: string ='sm'
    @State articleList: Array<{ title: string, content: string }> = [
        { title: 'News 1', content: 'The content of News 1' },
        { title: 'News 2', content: 'The content of News 2' }
    ]
    @State selectedArticleIndex: number = 0
    build() {
        GridRow({ breakpoints: { value: ['840vp'], reference: BreakpointsReference.WindowSize } }) {
            GridCol({ span: { sm: 12, md: 3, lg: 2 } }) {
                // Navigation Bar
                Column() {
                    ForEach(articleList, (article, index) => {
                        Text(article.title).fontSize(16).onClick(() => {
                            this.selectedArticleIndex = index
                        })
                    })
                }
            }
            GridCol({ span: { sm: 12, md: 6, lg: 4 } }) {
                // Information List
                List() {
                    ForEach(articleList, (article, index) => {
                        ListItem() {
                            Text(article.title).fontSize(16)
                        }
                    })
                }
            }
            GridCol({ span: { sm: 12, md: 12, lg: 6 } }) {
                // Article Details
                Column() {
                    Text(articleList[this.selectedArticleIndex].content).fontSize(14)
                }
            }
        }
          .onBreakpointChange((breakpoint: string) => {
                this.currentBreakpoint = breakpoint
            })
    }
}
Enter fullscreen mode Exit fullscreen mode

By listening to the changes in breakpoints, when the screen width is greater than 840vp, it is switched to the three-column mode to improve the efficiency of information display and operation on large-screen devices.

The Combination of Swiper + Grid to Adjust the Arrangement of Information Cards on Mobile Phones

On mobile phones, in order to improve the efficiency of users browsing news, the combination of Swiper + Grid is adopted to adjust the arrangement of information cards. Swiper is used to achieve the carousel effect of the cards to display popular news; Grid is used to reasonably arrange other news cards within the limited screen space.

@Entry
@Component
struct MobileNewsLayout {
    @State newsData: Array<{ title: string, image: Resource }> = [
        { title: 'News 1', image: $r('app.media.news1Image') },
        { title: 'News 2', image: $r('app.media.news2Image') },
        { title: 'News 3', image: $r('app.media.news3Image') }
    ]
    build() {
        Column() {
            Swiper() {
                ForEach(newsData.slice(0, 3), (news) => {
                    GridRow() {
                        GridCol({ span: 12 }) {
                            Column() {
                                Image(news.image).width('100%').height(150).objectFit(ImageFit.Contain)
                                Text(news.title).fontSize(16).textAlign(TextAlign.Center)
                            }
                        }
                    }
                })
            }
            .autoPlay(true).indicator(true)
            GridRow() {
                ForEach(newsData.slice(3), (news) => {
                    GridCol({ span: 6 }) {
                        Column() {
                            Image(news.image).width('100%').height(100).objectFit(ImageFit.Contain)
                            Text(news.title).fontSize(14).textAlign(TextAlign.Center)
                        }
                    }
                })
            }
        }
          .width('100%').height('100%')
    }
}
Enter fullscreen mode Exit fullscreen mode

In this way, not only can popular news be highlighted, but also more news content can be displayed within the limited screen space.

Adaptation in the Free Window Mode to Ensure that the Content Does Not Shift When the Window Is Adjusted

In the free window mode, to ensure that the content does not shift, the application needs to be optimized by combining adaptive and responsive layouts. By setting window size limit parameters, such as minWindowWidth, maxWindowHeight, etc., avoid layout confusion caused by excessive changes in the window size. At the same time, use the capabilities of line wrapping and hiding in the adaptive layout, as well as breakpoint adjustments in the responsive layout, to ensure that the content can be automatically re-typeset when the window size changes.

@Entry
@Component
struct FreeWindowAdaptiveLayout {
    @State currentBreakpoint: string ='sm'
    build() {
        GridRow({ breakpoints: { value: ['600vp'], reference: BreakpointsReference.WindowSize } }) {
            GridCol({ span: { sm: 12, md: 6 } }) {
                Column() {
                    // News Content
                    Text('This is a news content that needs to be displayed normally under different window sizes').fontSize(14)
                }
            }
            GridCol({ span: { sm: 12, md: 6 } }) {
                // Related Picture
                Image($r('app.media.newsImage')).width('100%').aspectRatio(1).when(this.currentBreakpoint ==='sm', (image) => image.height(100)).when(this.currentBreakpoint!=='sm', (image) => image.height(150))
            }
        }
          .onBreakpointChange((breakpoint: string) => {
                this.currentBreakpoint = breakpoint
            })
    }
}
Enter fullscreen mode Exit fullscreen mode

When the window size changes, adjust the layout in a timely manner by listening to breakpoints to ensure the normal display of the content.

Strategies for Optimizing the Experience and Dynamic Adaptation

Optimization through Media Queries: Dynamically Adjusting Fonts, Pictures, Spacing, etc. under Different Screen Sizes

Use media queries to dynamically adjust the font size, picture size, and spacing according to different screen sizes. On small-screen devices, appropriately reduce the font and picture sizes and increase the spacing between elements to facilitate user operation; on large-screen devices, increase the font and picture sizes and reduce the spacing to improve the density of information display.

@Entry
@Component
struct MediaQueryOptimization {
    @State currentBreakpoint: string ='sm'
    build() {
        Column() {
            Text('News Title').fontSize(this.currentBreakpoint ==='sm'? 16 : 20).fontWeight(500)
            Image($r('app.media.newsImage')).width(this.currentBreakpoint ==='sm'? 100 : 200).height(this.currentBreakpoint ==='sm'? 100 : 150).objectFit(ImageFit.Contain)
            Text('News Content').fontSize(this.currentBreakpoint ==='sm'? 12 : 14).opacity(0.8).padding({ top: this.currentBreakpoint ==='sm'? 5 : 10 })
        }
          .width('100%').height('100%')
          .onBreakpointChange((breakpoint: string) => {
                this.currentBreakpoint = breakpoint
            })
    }
}
Enter fullscreen mode Exit fullscreen mode

Presentation Modes of the Navigation Bar on Different Ends (Hiding, Folding, Sidebar Switching)

On mobile phones, to save screen space, the navigation bar can be hidden or folded, and users can evoke the navigation by clicking a specific button. On tablets and PCs, a sidebar form can be adopted to always display the navigation options for the convenience of user operation.

@Entry
@Component
struct NavBarAdaptation {
    @State isNavBarVisible: boolean = false
    @State currentBreakpoint: string ='sm'
    build() {
        Column() {
            if (this.currentBreakpoint ==='sm') {
                Button('Expand Navigation').onClick(() => {
                    this.isNavBarVisible =!this.isNavBarVisible
                })
                if (this.isNavBarVisible) {
                    Column() {
                        // Navigation Options
                        Text('Home').fontSize(16).onClick(() => { /* Navigation logic */ })
                        Text('Categories').fontSize(16).onClick(() => { /* Navigation logic */ })
                    }
                }
            } else {
                // Sidebar Navigation on Tablets and PCs
                SideBarContainer(SideBarContainerType.Embed) {
                    Column() {
                        Text('Home').fontSize(16).onClick(() => { /* Navigation logic */ })
                        Text('Categories').fontSize(16).onClick(() => { /* Navigation logic */ })
                    }
                }
                  .sideBarWidth(200).showSideBar(true)
            }
        }
          .width('100%').height('100%')
          .onBreakpointChange((breakpoint: string) => {
                this.currentBreakpoint = breakpoint
                if (breakpoint!=='sm') {
                    this.isNavBarVisible = true
                }
            })
    }
}
Enter fullscreen mode Exit fullscreen mode

User Interaction Optimization (Keyboard/Mouse Operations on Large-screen Ends vs. Touch Gestures on Mobile Ends)

On large-screen ends, make full use of the operation advantages of the keyboard and mouse, such as using keyboard shortcuts for navigation and operation, and displaying more information when the mouse hovers. On mobile ends, optimize touch gesture operations, such as swiping to browse the news list, clicking to expand the details, etc. By detecting the device input method, provide the most suitable interaction method for different devices to enhance the user experience.

@Entry
@Component
struct InteractionOptimization {
    @State deviceType: string = 'unknown'
    @State isHover: boolean = false
    aboutToAppear() {
        // Get the device type
        this.deviceType = deviceInfo.deviceType
    }
    build() {
        Column() {
            if (this.deviceType === 'tablet' || this.deviceType === 'pc') {
                // Large-screen End
                Text('News Title').fontSize(20).onHover((isHover) => {
                    this.isHover = isHover
                }).when(this.isHover, (text) => text.color('#0A59F7'))
            } else {
                // Mobile End
                Text('News Title').fontSize(16).onClick(() => { /* News details logic */ })
            }
        }
          .width('100%').height('100%')
    }
}
Enter fullscreen mode Exit fullscreen mode

Through the above architectural design for multi-terminal adaptation, layout optimization, and the comprehensive application of various technologies, we can create a news and information application that is adapted to all ends on HarmonyOS Next, providing users with a high-quality and consistent reading experience.

Top comments (0)