DEV Community

Cover image for Layout Overview
liu yang
liu yang

Posted on • Edited on

Layout Overview

How to Choose Layouts

When developing user interfaces in a declarative manner, selecting the right layout is crucial for creating efficient and visually appealing applications. The declarative UI framework provides a variety of layout options, each suited for different scenarios. This guide will help you understand when to use each layout and provide examples to illustrate their usage.

Layout Options

1. Linear Layout (Row, Column)

Application Scenario: Use this layout when you have multiple child elements that can be arranged linearly, either horizontally (Row) or vertically (Column).

Example:

@Entry
@Component
struct LinearExample {
  build() {
    Column() {
      Text('Item 1')
      Text('Item 2')
      Text('Item 3')
    }
    .width('100%')
    .height('100%')

    Row() {
      Text('Item A')
      Text('Item B')
      Text('Item C')
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Stacked Layout (Stack)

Application Scenario: Use this layout when components need to overlap each other. The stacking effect does not affect the layout space of other child components in the same container.

Example:

@Entry
@Component
struct StackExample {
  build() {
    Stack() {
      Rectangle()
        .width('100%')
        .height('100%')
        .backgroundColor(Color.Red)
      Text('Overlay Text')
        .fontSize(20)
        .color(Color.White)
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Flexible Layout (Flex)

Application Scenario: Similar to linear layout, but with the ability to compress or stretch child components by default. Use this layout when child components need to calculate stretching or compressing ratios.

Example:

@Entry
@Component
struct FlexExample {
  build() {
    Flex() {
      Text('Item 1')
        .flexGrow(1)
      Text('Item 2')
        .flexGrow(2)
      Text('Item 3')
        .flexGrow(1)
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Relative Layout (RelativeContainer)

Application Scenario: Use this layout for complex page elements or when linear layout would result in too many nested container layers. Child components can align their positions with the container or other child components.

Example:

@Entry
@Component
struct RelativeExample {
  build() {
    RelativeContainer() {
      Text('Top Left')
        .alignRules({ top: 0, left: 0 })
      Text('Center')
        .alignRules({ center: true })
      Text('Bottom Right')
        .alignRules({ bottom: 0, right: 0 })
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Grid Layout (GridRow, GridCol)

Application Scenario: Use this layout when you need to divide space into regular grids, especially for multi-device scenarios.

Example:

@Entry
@Component
struct GridExample {
  build() {
    GridRow(columnsTemplate: 'repeat(3, 1fr)') {
      GridCol(columnsIndex: '0 / 1') {
        Text('Item 1')
      }
      GridCol(columnsIndex: '1 / 2') {
        Text('Item 2')
      }
      GridCol(columnsIndex: '2 / 3') {
        Text('Item 3')
      }
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

6. Media Query (@ohos.mediaquery)

Application Scenario: Use media queries to modify the application's style based on different device types or states.

Example:

@Entry
@Component
struct MediaQueryExample {
  build() {
    Column() {
      Text('Responsive Text')
        .fontSize(MediaQuery.textScaleFactor(this.context) > 1 ? 24 : 18)
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

7. List

Application Scenario: Use lists to efficiently display structured and scrollable information.

Example:

@Entry
@Component
struct ListExample {
  build() {
    List() {
      ListItem() {
        Text('Item 1')
      }
      ListItem() {
        Text('Item 2')
      }
      ListItem() {
        Text('Item 3')
      }
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

8. Grid

Application Scenario: Use grid layout for strong page division and control over the proportion of child elements.

Example:

@Entry
@Component
struct GridExample {
  build() {
    Grid(columnsTemplate: 'repeat(2, 1fr)', rowsTemplate: 'repeat(2, 1fr)') {
      Text('Item 1')
        .gridColumn('1 / 2')
        .gridRow('1 / 2')
      Text('Item 2')
        .gridColumn('2 / 3')
        .gridRow('1 / 2')
      Text('Item 3')
        .gridColumn('1 / 2')
        .gridRow('2 / 3')
      Text('Item 4')
        .gridColumn('2 / 3')
        .gridRow('2 / 3')
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

9. Swiper

Application Scenario: Use the Swiper component for ad rotation and image previews.

Example:

@Entry
@Component
struct SwiperExample {
  build() {
    Swiper() {
      SwiperItem() {
        Image($r('app.media.image1'))
          .width('100%')
          .height('100%')
      }
      SwiperItem() {
        Image($r('app.media.image2'))
          .width('100%')
          .height('100%')
      }
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

10. Tabs

Application Scenario: Use tabs to quickly switch view content within a single page.

Example:

@Entry
@Component
struct TabsExample {
  build() {
    Tabs() {
      TabPane(label: 'Tab 1') {
        Text('Content of Tab 1')
      }
      TabPane(label: 'Tab 2') {
        Text('Content of Tab 2')
      }
      TabPane(label: 'Tab 3') {
        Text('Content of Tab 3')
      }
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Layout Position

Positioning Capabilities

Absolute Positioning

Use Case: Less adaptable to different screen sizes.

Implementation:

@Entry
@Component
struct AbsoluteExample {
  build() {
    Column() {
      Text('Absolute Text')
        .position({ top: 50, left: 50 })
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Relative Positioning

Use Case: Adjusts the position relative to itself.

Implementation:

@Entry
@Component
struct RelativeExample {
  build() {
    Column() {
      Text('Relative Text')
        .offset({ x: 50, y: 50 })
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Constraints on Child Elements

Stretching

flexGrow and flexShrink Properties:

  • flexGrow controls the stretching of components based on the remaining space of the parent container.
  • flexShrink controls the compression of components based on the compressed size of the parent container.

Example:

@Entry
@Component
struct StretchExample {
  build() {
    Flex() {
      Text('Item 1')
        .flexGrow(1)
        .flexShrink(1)
      Text('Item 2')
        .flexGrow(2)
        .flexShrink(2)
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Scaling

aspectRatio Property:

  • The aspectRatio property specifies the width-to-height ratio of the current component to control scaling.

Example:

@Entry
@Component
struct ScaleExample {
  build() {
    Column() {
      Image($r('app.media.image'))
        .aspectRatio(16 / 9)
    }
    .width('100%')
    .height('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)