Excelente ejemplo de HarmonyOS Codelab: aplicación de compras, experimente el encanto del desarrollo único y la implementación múltiple

 

1. Introducción de muestra

Este Codelab se basa en un diseño adaptativo y un diseño responsivo para permitir que las aplicaciones de compras se muestren con diferentes diseños en teléfonos móviles, pantallas plegables y tabletas con diferentes tamaños de pantalla. Organice el código a través de una estructura de ingeniería de tres capas para lograr un desarrollo único y una implementación en múltiples extremos.

El efecto de funcionamiento del teléfono móvil se muestra en la figura:

 

Representaciones de operación de pantalla plegable:

 

Diagrama de efectos de ejecución de tableta:

Conceptos relacionados

  • Desarrollar una vez e implementar en múltiples terminales : un conjunto de proyectos de código se desarrolla una vez y se implementa en múltiples terminales según demanda. Ayude a los desarrolladores a desarrollar de manera rápida y eficiente aplicaciones que admitan una variedad de formas de dispositivos terminales.
  • Diseño adaptativo : cuando cambia el tamaño del contenedor exterior, los elementos pueden cambiar automáticamente de acuerdo con sus relaciones relativas para adaptarse a las capacidades de diseño de los cambios en el contenedor exterior. Relaciones relativas como proporción, relación de aspecto fija, prioridad de visualización, etc. Actualmente existen 7 tipos de capacidades de diseño adaptativo: capacidad de extensión, capacidad de ecualización, capacidad de proporción, capacidad de zoom, capacidad de extensión, capacidad de ocultación y capacidad de ajuste de línea. La capacidad de diseño adaptable permite que la visualización de la interfaz cambie continuamente con el tamaño del contenedor externo.
  • Diseño responsivo : cuando cambia el tamaño del contenedor externo, los elementos pueden cambiar automáticamente según puntos de interrupción, cuadrículas o características específicas (como la orientación de la pantalla, el ancho de la ventana, la altura, etc.) para adaptarse a las capacidades de diseño del contenedor externo. Actualmente existen tres tipos de capacidades de diseño responsivo: puntos de interrupción, consultas de medios y diseño de cuadrícula.
  • GridRow : componente contenedor de cuadrícula, que solo se puede usar con el subcomponente de cuadrícula (GridCol) en escenarios de diseño de cuadrícula.
  • GridCol : Subcomponente de cuadrícula, debe usarse como subcomponente del componente contenedor de cuadrícula (GridRow).

Ejemplo completo : dirección del código fuente de gitee

2. Configuración del entorno

Primero debemos completar el establecimiento del entorno de desarrollo HarmonyOS, consulte los siguientes pasos.

Requisitos de Software

Requisitos de hardware

  • Tipo de dispositivo: teléfono móvil Huawei o simulador de dispositivo de teléfono móvil Huawei que se ejecuta en DevEco Studio.
  • Sistema HarmonyOS: versión para desarrolladores 3.1.0 y superiores.

Construcción del entorno

  1. Instale DevEco Studio. Para obtener más información, consulte Descargar e instalar software .
  2. Configure el entorno de desarrollo de DevEco Studio. El entorno de desarrollo de DevEco Studio depende del entorno de red. Debe estar conectado a la red para garantizar el uso normal de la herramienta. Puede configurar el entorno de desarrollo de acuerdo con las dos situaciones siguientes:
  1. Los desarrolladores pueden consultar el siguiente enlace para completar la configuración relevante de depuración del dispositivo:

3. Interpretación de la estructura del código.

Este Codelab solo explica el código central: común es la capa de capacidad pública, la característica es la capa del módulo funcional, este ejemplo se divide en seis módulos y el producto es la capa del producto. Para obtener el código completo, lo proporcionaremos en la descarga del código fuente o en gitee.

├──common/src/main/ets               // 公共能力层
│  ├──bean
│  │  ├──CommodityModel.ets          // 商品数据实体类
│  │  ├──OrderModel.ets              // 订单数据实体类
│  │  └──ProductModel.ets            // 购物车商品数据实体类
│  ├──components
│  │  ├──CommodityList.ets           // 商品列表组件
│  │  ├──CounterProduct.ets          // 数量加减组件
│  │  └──EmptyComponent.ets          // 无数据显示组件
│  ├──constants
│  │  ├──BreakpointConstants.ets     // 断点常量类
│  │  ├──GridConstants.ets           // 栅格常量类
│  │  └──StyleConstants.ets          // 样式常量类
│  ├──utils
│  │  ├──BreakpointSystem.ets        // 断点工具类
│  │  ├──CommonDataSource.ets        // 数据封装类
│  │  ├──LocalDataManager.ets        // 数据操作管理类
│  │  ├──Logger.ets.ets              // 日志工具类
│  │  └──Utils.ets                   // 方法工具类
│  └──viewmodel
│     └──ShopData.ets                // 商品应用数据
├──features                          // 功能模块层
│  ├──commoditydetail/src/main/ets   // 商品详情内容区
│  │  ├──bean
│  │  │  └──TypeModel.ets            // 实体类
│  │  ├──components
│  │  │  ├──CapsuleGroupButton.ets   // 自定义按钮组件
│  │  │  ├──CommodityDetail.ets      // 商品详情组件
│  │  │  └──SpecificationDialog.ets  // 商品规格弹框
│  │  ├──constants
│  │  │  └──CommodityConstants.ets   // 商品详情区常量类
│  │  └──viewmodel
│  │     └──CommodityDetailData.ets  // 商品详情数据类
│  ├──home/src/main/ets              // 首页内容区
│  │  ├──components
│  │  │  └──Home.ets                 // 首页内容组件
│  │  └──viewmodel
│  │     └──HomeData.ets             // 首页数据
│  ├──newproduct/src/main/ets        // 新品内容区
│  │  ├──components
│  │  │  └──NewProduct.ets           // 新品内容组件
│  │  └──viewmodel
│  │     └──NewProductData.ets       // 新品数据
│  ├──orderdetail/src/main/ets       // 订单相关内容区
│  │  ├──components
│  │  │  ├──AddressInfo.ets          // 收件人信息组件
│  │  │  ├──CommodityOrderItem.ets   // 商品订单信息组件
│  │  │  ├──CommodityOrderList.ets   // 商品订单列表组件
│  │  │  ├──ConfirmOrder.ets         // 确认订单组件
│  │  │  ├──HeaderBar.ets            // 标题组件
│  │  │  ├──OrderDetailList.ets      // 订单分类列表组件
│  │  │  ├──OrderListContent.ets     // 订单分类列表内容组件
│  │  │  └──PayOrder.ets             // 支付订单组件
│  │  ├──constants
│  │  │  └──OrderDetailConstants.ets // 订单区常量类
│  │  └──viewmodel
│  │     └──OrderData.ets            // 订单数据
│  ├──personal/src/main/ets          // 我的内容区
│  │  ├──bean
│  │  │  └──IconButtonModel.ets      // 按钮图标实体类
│  │  ├──components
│  │  │  ├──IconButton.ets           // 图片按钮组件
│  │  │  ├──LiveList.ets             // 直播列表组件
│  │  │  └──Personal.ets             // 我的内容组件
│  │  ├──constants
│  │  │  └──PersonalConstants.ets    // 我的常量类
│  │  └──viewmodel
│  │     └──PersonalData.ets         // 我的数据
│  └──shopcart/src/main/ets          // 购物车内容区
│     ├──components
│     │  └──ShopCart.ets             // 购物车内容组件
│     └──constants
│        └──ShopCartConstants.ets    // 购物车常量类
└──products                          // 产品层
   └──phone/src/main/ets             // 支持手机、平板
      ├──constants
      │  └──PageConstants.ets        // 页面常量类
      ├──entryability
      │  └──EntryAbility.ets          // 程序入口类
      ├──pages
      │  ├──CommodityDetailPage.ets  // 订单详情页
      │  ├──ConfirmOrderPage.ets     // 确认订单页
      │  ├──MainPage.ets             // 主页
      │  ├──OrderDetailListPage.ets  // 订单分类列表页
      │  ├──PayOrderPage.ets         // 支付订单页
      │  └──SplashPage.ets           // 启动过渡页
      └──viewmodel
         └──MainPageData.ets         // 主页数据

4. Marco principal de la aplicación

4.1 Página de inicio

En el directorio de páginas del proyecto, seleccione Index.ets, haga clic con el botón derecho en > Refactorizar > Cambiar nombre y cámbiele el nombre a SplashPage.ets. Después de cambiar el nombre, modifique el primer parámetro del método windowStage.loadContent en el archivo EntryAbility.ets en el directorio de entrada del proyecto a páginas/SplashPage. Agregue una tarea programada de 2 segundos a la función periódica de la página aboutToAppear para saltar a la página de inicio.

// EntryAbility.ets
windowStage.loadContent('pages/SplashPage', (err, data) => {
                     
                     
  if (err.code) {
                     
                     
    ...
  }
});

// SplashPage.ets
build() {
                     
                     
  Column() {
                     
                     
    ...
  }
  .height(StyleConstants.FULL_HEIGHT)
  .width(StyleConstants.FULL_WIDTH)
  .backgroundColor($r('app.color.page_background'))
}

aboutToAppear() {
                     
                     
  this.breakpointSystem.register();
  this.timeOutId = setTimeout(() => {
                     
                     
    router.replaceUrl({
                     
                      url: PageConstants.MAIN_PAGE_URL })
      .catch(err => {
                     
                     
        Logger.error(JSON.stringify(err));
      })
  }, PageConstants.DELAY_TIME);
}

aboutToDisappear() {
                     
                     
  this.breakpointSystem.unregister();
  clearTimeout(this.timeOutId);
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

4.2 Página de inicio

La página de inicio de este Codelab se compone del componente contenedor Tabs y cuatro subcomponentes TabContent. Las vistas de contenido de las cuatro pestañas TabContent son Inicio, Nuevo producto, ShopCart y Personal. De acuerdo con el escenario de uso del usuario, a través de la consulta de medios del diseño responsivo, monitoree el cambio en el ancho de la ventana de la aplicación, obtenga el valor del punto de interrupción de la aplicación actual, establezca la posición de las pestañas, el punto de interrupción de LG, como la tableta, mostrará la barra lateral y otros puntos de interrupción. Se muestra la barra inferior.

/// MainPage.ets
build() {
                         
                         
  Column() {
                         
                         
    Tabs({
                         
                         
      barPosition: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
        BarPosition.Start : BarPosition.End,
      index: this.currentPageIndex
    }) {
                         
                                
    ...  
    .barWidth(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
      $r('app.float.bar_width') : StyleConstants.FULL_WIDTH)
    .barHeight(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
      StyleConstants.SIXTY_HEIGHT : $r('app.float.vp_fifty_six'))
    .vertical(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG)
  }
  .backgroundColor($r('app.color.page_background'))
}

Visualización de la página de inicio:

5. Introducción a la página

5.1 Página de la pestaña Inicio

La pestaña de la página de inicio realiza diseños como cuadros de búsqueda y categorías a través de las capacidades de ecualización y extensión del diseño adaptable, y establece la cantidad de imágenes de carrusel y listas de productos a través de las capacidades de consulta de medios y puntos de interrupción del diseño responsivo.

A través de la consulta de medios del diseño responsivo, supervise el cambio en el ancho de la ventana de la aplicación, obtenga el valor del punto de interrupción de la aplicación actual, establezca el número de columnas de la lista de productos y las imágenes del carrusel, el punto de interrupción lg muestra 4 columnas y 3 imágenes del carrusel, el punto de interrupción md muestra 3 columnas y 2 imágenes de carrusel, sm breakpoint muestra 2 columnas y 1 imagen de carrusel.

// Home.ets
@Builder CustomSwiper() {
                             
                             
  Swiper() {
                             
                             
    ForEach(swiperImage, (item: Resource) => {
                             
                             
      Image(item)
        .width(StyleConstants.FULL_WIDTH)
        .aspectRatio(StyleConstants.IMAGE_ASPECT_RATIO)
    }, item => JSON.stringify(item))
  }
  .itemSpace(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ? 0 :
    StyleConstants.ITEM_SPACE)
  .indicator(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM)
  .displayCount(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ?
    StyleConstants.DISPLAY_THREE :
    (this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ? StyleConstants.DISPLAY_TWO :
    StyleConstants.DISPLAY_ONE))
}

// Home.ets
CommodityList({
                             
                             
  commodityList: $commodityList,
  column: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.DISPLAY_FOUR :
    (this.currentBreakpoint === BreakpointConstants.BREAKPOINT_MD ?
    StyleConstants.DISPLAY_THREE : StyleConstants.DISPLAY_TWO),
  onClickItem: (data: Commodity) => this.onClickItem(data)
})

// CommodityList.ets
build() {
                             
                             
  if (this.commodityList.length > 0) {
                             
                             
    List({ space: StyleConstants.TWELVE_SPACE }) {
                             
                             
      LazyForEach(new CommonDataSource(this.commodityList), (item: Commodity) => {
                             
                             
        ...
      }, item => JSON.stringify(item))
    }
    ...
    .lanes(this.column)
  } else {
                             
                             
    EmptyComponent({
                             
                              outerHeight: StyleConstants.FIFTY_HEIGHT })
  }
}

Usando la capacidad de ecualización del diseño adaptativo, establezca la alineación en el eje principal en FlexAlign.SpaceAround en el diseño Flex, de modo que la distancia entre los componentes representados en el ciclo sea la misma, la distancia entre el primer elemento y el comienzo de la línea. y la distancia entre el último elemento y el final de la línea. La distancia es la mitad de la distancia entre elementos adyacentes.

// Home.ets
@Builder ActivityTitle() {
                             
                             
  Flex({ justifyContent: FlexAlign.SpaceAround }) {
                             
                             
    ForEach(activityTitle, (item: ActivityTitleModel, index: number) => {
                             
                             
      Flex({
                             
                             
        direction: FlexDirection.Column,
        justifyContent: FlexAlign.Center,
        alignItems: ItemAlign.Center
      }) {
                             
                             
        ...
      }
    }, item => JSON.stringify(item))
  }
  ...
}

Diagrama de efectos de ejecución del teléfono móvil:

Diagrama de efecto de funcionamiento de pantalla plegable.

Diagrama de efectos de ejecución de tableta

5.2 Pestaña Nuevo Producto

La página de pestaña de nuevo producto se compone de un carrusel, una clasificación y una lista de nuevos productos. A través de la consulta de medios del diseño responsivo, la capacidad de punto de interrupción y la capacidad de ecualización del diseño adaptativo, diferentes tipos de dispositivos pueden mostrar diferentes efectos y lograr el La misma lógica que la página de inicio.

A través de la consulta de medios del diseño receptivo, supervise el cambio en el ancho de la ventana de la aplicación, obtenga el valor del punto de interrupción de la aplicación actual y establezca la nueva lista de productos. El punto de interrupción sm muestra 2 columnas y los puntos de interrupción md y lg muestran 3 columnas. .

// NewProduct.ets
@Builder ProductList() {
                               
                               
  List({ space: StyleConstants.TWELVE_SPACE }) {
                               
                               
    LazyForEach(new CommonDataSource(productData), (item: ProductDataModel) => {
                               
                               
      ListItem() {
                               
                               
        ...
    }, item => JSON.stringify(item))
  }
  .lanes(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM ?
    StyleConstants.DISPLAY_TWO : StyleConstants.DISPLAY_THREE)
  .padding({
                               
                                left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
}

Diagrama de efectos de ejecución del teléfono móvil:

Diagrama de efecto de funcionamiento de pantalla plegable.

Diagrama de efectos de ejecución de tableta

5.3 Pestaña Carrito de compras

La página de la pestaña del carrito de compras se compone de una lista de carritos de compras y una lista de productos. La lógica de implementación de la lista de productos es la misma que la lista de productos en la página de inicio. La lista de carritos de compras se implementa utilizando la capacidad de ecualización del diseño adaptativo.

// ShopCart.ets
@Builder CartItem(item: Product, index: number) {
                                 
                                 
  Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
                                 
                                 
    ...
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceAround }) {
                                 
                                 
      Text($r('app.string.commodity_piece_description', item.name, item.description))
        ...
      Text(`${Object.values(item.specifications).join(',')}`)
        ...
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
                                 
                                 
        Text() {
                                 
                                 
          ...
        }

        CounterProduct({
                                 
                                 
          count: item.count,
          onNumberChange: (num: number) => {
                                 
                                 
            this.onChangeCount(num, item);
          }
        })
      }
    }
    ...
  }
}

Diagrama de efectos de ejecución del teléfono móvil:

Diagrama de efecto de funcionamiento de pantalla plegable.

Diagrama de efectos de ejecución de tableta

5.4 Mis pestañas

Mi página de pestañas se compone principalmente de información personal, mis pedidos, botones de texto e imágenes y lista de transmisión en vivo. El plan de implementación de la lista de transmisión en vivo es el mismo que el de la lista de productos de la página de inicio. Otros utilizan la capacidad de ecualización del diseño adaptativo. La alineación en el eje principal del diseño Flex se establece en FlexAlign.SpaceAround.

// Personal.ets
@Builder Order() {
                                   
                                   
  Flex({direction: FlexDirection.Column}) {
                                   
                                   
    Flex({
                                   
                                   
      justifyContent: FlexAlign.SpaceBetween,
      alignItems: ItemAlign.Center
    }) {
                                   
                                   
      Text($r('app.string.order_mine'))
        .fontSize($r('app.float.middle_font_size'))
      Row() {
                                   
                                   
        ...
      }
      ...
      })
    }
  Flex({
                                   
                                   
    justifyContent: FlexAlign.SpaceAround,
    alignItems: ItemAlign.Center
  }) {
                                   
                                   
    ForEach(this.orderIconButton, (iconButton: IconButtonModel) => {
                                   
                                   
      IconButton({
                                   
                                   
        props: iconButton,
        click: this.onOrderButtonClick.bind(this, iconButton.key)
      })
    }, (iconButton) => JSON.stringify(iconButton))
  }
  .width(StyleConstants.FULL_WIDTH)
}

@Builder IconDock(buttons: IconButtonModel[]) {
                                   
                                   
  Flex({
                                   
                                   
    justifyContent: FlexAlign.SpaceAround,
    alignItems: ItemAlign.Center
  }) {
                                   
                                   
    ForEach(buttons, (iconButton: IconButtonModel) => {
                                   
                                   
      IconButton({
                                   
                                   
        props: iconButton
      })
    }, (iconButton) => JSON.stringify(iconButton))
  }
  .height($r('app.float.icon_dock_height'))
  .padding($r('app.float.vp_twelve'))
  .cardStyle()
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

5.5 Página de detalles del producto

La página de detalles del producto en su conjunto consta de una imagen de carrusel, información del producto y una barra de botones inferior. A través del diseño de cuadrícula con capacidades de diseño responsivo, diferentes tipos de dispositivos pueden mostrar diferentes efectos y a través de las capacidades de extensión del diseño adaptativo, el El atributo flexGrow se puede configurar en El botón está en la parte inferior.

  • Bajo el punto de interrupción sm, la imagen del carrusel ocupa 4 cuadrículas, la información del producto ocupa 4 cuadrículas y la barra de botones inferior ocupa 4 cuadrículas.
  • Bajo el punto de interrupción md, la imagen del carrusel ocupa 8 cuadrículas, la información del producto ocupa 8 cuadrículas y la barra de botones inferior ocupa 8 cuadrículas.
  • Bajo el punto de interrupción de LG, la imagen del carrusel ocupa 12 cuadrículas, la información del producto ocupa 8 cuadrículas y está compensada por 2 cuadrículas, y la barra de botones inferior ocupa 8 cuadrículas y está compensada por 2 cuadrículas.

// CommodityDetail.ets
build() {
                                     
                                     
  Stack({ alignContent: Alignment.TopStart }) {
                                     
                                     
    Flex({ direction: FlexDirection.Column }) {
                                     
                                     
      Scroll() {
                                     
                                     
        GridRow({
                                     
                                     
          columns: {
                                     
                                     
            sm: GridConstants.COLUMN_FOUR,
            md: GridConstants.COLUMN_EIGHT,
            lg: GridConstants.COLUMN_TWELVE
          },
          gutter: GridConstants.GUTTER_TWELVE
        }) {
                                     
                                     
          GridCol({
                                     
                                     
            span: {
                                     
                                     
              sm: GridConstants.SPAN_FOUR,
              md: GridConstants.SPAN_EIGHT,
              lg: GridConstants.SPAN_TWELVE }
          }) {
                                     
                                     
            this.CustomSwiper(this.info.images)
          }
          GridCol({
                                     
                                     
            span: {
                                     
                                     
              sm: GridConstants.SPAN_FOUR,
              md: GridConstants.SPAN_EIGHT,
              lg: GridConstants.SPAN_EIGHT
            },
            offset: { lg: GridConstants.OFFSET_TWO }
          }) {
                                     
                                     
            Column() {
                                     
                                     
              ...
            }
          }
        }
      }
      .flexGrow(StyleConstants.FLEX_GROW)
      GridRow({
                                     
                                     
        columns: {
                                     
                                     
          sm: GridConstants.COLUMN_FOUR,
          md: GridConstants.COLUMN_EIGHT,
          lg: GridConstants.COLUMN_TWELVE
        },
        gutter: GridConstants.GUTTER_TWELVE
      }) {
                                     
                                     
        GridCol({
                                     
                                     
          span: {
                                     
                                     
            sm: GridConstants.SPAN_FOUR,
            md: GridConstants.SPAN_EIGHT,
            lg: GridConstants.SPAN_EIGHT
          },
          offset: { lg: GridConstants.OFFSET_TWO } }) {
                                     
                                     
          this.BottomMenu()
        }
      }
    }
    ...
  }
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

5.6 Página de confirmación del pedido

La página de confirmación del pedido consta de la información del recibo en la parte superior, la información del pedido, el precio total en la parte inferior y el botón de enviar pedido. A través del diseño de cuadrícula receptivo, diferentes tipos de dispositivos pueden mostrar diferentes efectos y a través de la capacidad de extensión del Diseño adaptable. Configure la propiedad flexGrow para que los botones de precio total y enviar pedido estén en la parte inferior.

  • Bajo el punto de interrupción sm, la información del recibo y la información del pedido en la parte superior ocupan 4 cuadrículas, el precio total en la parte inferior ocupa 2 cuadrículas y el botón de envío de pedido en la parte inferior ocupa 2 cuadrículas.
  • Bajo el punto de interrupción md, la información del recibo superior y la información del pedido ocupan 8 cuadrículas, el precio total inferior ocupa 2 cuadrículas y el botón inferior ocupa 3 cuadrículas y está compensado por 3 cuadrículas.
  • Bajo el punto de interrupción de LG, la información del recibo y la información del pedido en la parte superior ocupan 8 cuadrículas y se compensan con 2 cuadrículas, el precio total en la parte inferior ocupa 2 cuadrículas y se compensa con 2 cuadrículas, y el botón inferior ocupa 3 cuadrículas y se compensa por 3 rejillas.

// ConfirmOrder.ets
build() {
                                       
                                       
  Flex({ direction: FlexDirection.Column }) {
                                       
                                       
    HeaderBar({
                                       
                                       
      ...
    })
    Column(){
                                       
                                       
      Scroll() {
                                       
                                       
        GridRow({
                                       
                                       
          columns: {
                                       
                                       
            sm: GridConstants.COLUMN_FOUR,
            md: GridConstants.COLUMN_EIGHT,
            lg: GridConstants.COLUMN_TWELVE
            }
          }) {
                                       
                                       
          GridCol({
                                       
                                       
            span: {
                                       
                                       
              sm: GridConstants.SPAN_FOUR,
              md: GridConstants.SPAN_EIGHT,
              lg: GridConstants.SPAN_EIGHT
            },
            offset: { lg: GridConstants.OFFSET_TWO }
          }) {
                                       
                                       
            Column() {
                                       
                                       
              AddressInfo()
              CommodityOrderList()
            }
          }
        }
      }
      .scrollBar(BarState.Off)
    }
    .flexGrow(StyleConstants.FLEX_GROW)
    .padding({
                                       
                                        left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
    GridRow({
                                       
                                       
      columns: {
                                       
                                       
        sm: GridConstants.COLUMN_FOUR,
        md: GridConstants.COLUMN_EIGHT,
        lg: GridConstants.COLUMN_TWELVE
      },
      gutter: GridConstants.GUTTER_TWELVE
    }) {
                                       
                                       
      GridCol({
                                       
                                       
        span: {
                                       
                                       
          sm: GridConstants.SPAN_TWO,
          md: GridConstants.SPAN_TWO,
          lg: GridConstants.SPAN_TWO
        },
        offset: { lg: GridConstants.OFFSET_TWO }
      }) {
                                       
                                       
        Text($r('app.string.bottom_bar_amount', this.amount))
        ...
      }
      GridCol({
                                       
                                       
        span: {
                                       
                                       
          sm: GridConstants.SPAN_TWO,
          md: GridConstants.SPAN_THREE,
          lg: GridConstants.SPAN_THREE
        },
        offset: {
                                       
                                       
          md: GridConstants.OFFSET_THREE,
          lg: GridConstants.OFFSET_THREE
        }
      }) {
                                       
                                       
        Button($r('app.string.bottom_bar_button'))
          ...
      }
    }
    ...
  }
  ...
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

5.7 Página de pago del pedido

La página de pago del pedido se compone de la información del pedido en la parte superior y el botón de pago en la parte inferior. Al utilizar el diseño de cuadrícula del diseño responsivo, diferentes tipos de dispositivos pueden mostrar diferentes efectos y, a través de la capacidad de extensión del diseño adaptativo, el El atributo flexGrow está configurado para habilitar el botón de pago. Ubicado en la parte inferior.

  • Bajo el punto de interrupción sm, la información del pedido en la parte superior ocupa 4 cuadrículas y el botón de pago en la parte inferior ocupa 2 cuadrículas y está compensado por 2 cuadrículas.
  • Bajo el punto de interrupción md, la información del pedido en la parte superior ocupa 8 cuadrículas y el botón de pago en la parte inferior ocupa 2 cuadrículas y está compensado por 6 cuadrículas.
  • Bajo el punto de interrupción de LG, la información del pedido en la parte superior ocupa 8 cuadrículas y está compensada por 2 cuadrículas, y el botón de pago en la parte inferior ocupa 2 cuadrículas y está compensada por 8 cuadrículas.

// PayOrder.ets
build() {
                                         
                                         
  Flex({ direction: FlexDirection.Column }) {
                                         
                                         
    HeaderBar({
                                         
                                         
      ...
    })
    Stack({ alignContent: Alignment.TopStart }) {
                                         
                                         
      ...
      Column() {
                                         
                                         
        Scroll() {
                                         
                                         
          GridRow({
                                         
                                         
            columns: {
                                         
                                         
              sm: GridConstants.COLUMN_FOUR,
              md: GridConstants.COLUMN_EIGHT,
              lg: GridConstants.COLUMN_TWELVE
            }
          }) {
                                         
                                         
            GridCol({
                                         
                                         
              span: {
                                         
                                         
                sm: GridConstants.SPAN_FOUR,
                md: GridConstants.SPAN_EIGHT,
                lg: GridConstants.SPAN_EIGHT
              },
              offset: { lg: GridConstants.OFFSET_TWO }
            }) {
                                         
                                         
              Column() {
                                         
                                         
                this.OrderStatus()
                ...
              }
            }
          }
        }
        .scrollBar(BarState.Off)
      }
      .padding({
                                         
                                          left: $r('app.float.vp_twelve'), right: $r('app.float.vp_twelve') })
    }
    .flexGrow(StyleConstants.FLEX_GROW)

    GridRow({
                                         
                                         
      columns: {
                                         
                                         
        sm: GridConstants.COLUMN_FOUR,
        md: GridConstants.COLUMN_EIGHT,
        lg: GridConstants.COLUMN_TWELVE
      }
    }) {
                                         
                                         
      GridCol({
                                         
                                         
        span: {
                                         
                                         
          sm: GridConstants.SPAN_TWO,
          md: GridConstants.SPAN_TWO,
          lg: GridConstants.SPAN_TWO
        },
        offset: {
                                         
                                         
          sm: GridConstants.OFFSET_TWO,
          md: GridConstants.OFFSET_SIX,
          lg: GridConstants.OFFSET_EIGHT
        }
      }) {
                                         
                                         
        this.BottomBar()
      }
    }
  }
  ...
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

5.8 Página de lista de pedidos

El diseño general de la página de lista de pedidos utiliza un diseño de cuadrícula receptivo para lograr diferentes efectos de visualización para diferentes tipos de dispositivos.

  • Bajo el punto de interrupción sm, la UX general ocupa 4 cuadrículas.
  • Bajo el punto de interrupción md, la UX general ocupa 8 cuadrículas.
  • Bajo el punto de interrupción lg, la UX general ocupa 8 cuadrículas y está compensada por 2 cuadrículas.

// OrderListContent.ets
build() {
                                           
                                           
  Column() {
                                           
                                           
    Scroll() {
                                           
                                           
      GridRow({
                                           
                                           
        columns: {
                                           
                                           
          sm: GridConstants.COLUMN_FOUR,
          md: GridConstants.COLUMN_EIGHT,
          lg: GridConstants.COLUMN_TWELVE
        }
      }) {
                                           
                                           
        GridCol({
                                           
                                           
          span: {
                                           
                                           
            sm: GridConstants.SPAN_FOUR,
            md: GridConstants.SPAN_EIGHT,
            lg: GridConstants.SPAN_EIGHT
          },
          offset: { lg: GridConstants.OFFSET_TWO }
        }) {
                                           
                                           
          Column() {
                                           
                                           
            ...
          }
        }
      }
    }
    .scrollBar(BarState.Off)
  }
  ...
}

Diagrama de efectos de ejecución del teléfono móvil:

Representaciones de operación de pantalla plegable:

Diagrama de efectos de ejecución de tableta:

6. Resumen

Ha completado este estudio de Codelab y ha aprendido los siguientes puntos de conocimiento:

  1. Complete un diseño de página de desarrollo e implementación múltiple para dispositivos con diferentes tamaños de pantalla.
  2. Divida módulos y organice códigos según la estructura de ingeniería de tres capas.
  3. A través del diseño adaptativo, el diseño responsivo y el diseño de cuadrícula, se logra el desarrollo único y la implementación múltiple.

Supongo que te gusta

Origin blog.csdn.net/HarmonyOSDev/article/details/132532705
Recomendado
Clasificación