ETJava Beta | Java    注册   登录
  • 搜索:
  • 鸿蒙Banner图一多适配不同屏幕

    发表于      阅读(1)     博客类别:Crawler     转自:https://www.cnblogs.com/zhaloe/p/18525759
    如有侵权 请联系我们删除  (页面底部联系我们)  

    认识一多

    随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用、互助共享,让用户享受无缝的全场景体验。而作为应用开发者,广泛的设备类型也能为应用带来广大的潜在用户群体。但是如果一个应用需要在多个设备上提供同样的内容,则需要适配不同的屏幕尺寸和硬件,开发成本较高。HarmonyOS系统面向多终端提供了“一次开发,多端部署”(后文中简称为“一多”)的能力,让开发者可以基于一种设计,高效构建多端可运行的应用。

    img

    “一多”建议从最初的设计阶段开始就拉通多设备综合考虑。考虑实际智能终端设备种类繁多,设计师无法针对每种具体设备各自出一份UX设计图。“一多”建议从设备屏幕宽度的维度,将设备划分为六大类。设计师只需要针对这六大类设备做设计,而无需关心具体的设备形态。

    Banner图一多适配

    我们在使用Banner图时,会发现在中大屏设备上,Banner的宽度太大,当我们将高度固定时,在大屏设备上,高度又太小,图片裁剪严重。若宽高采用比例设置,高度又太大,在不同的屏幕上要么太小或太大,显示效果都不是很理想。

    Banner有一个属性displayCount,用来控制一屏显示多少个组件,我们在小屏设备上显示一张图片,在中大屏设备上一屏显示2张图片。再使用aspectRatio设置合适的宽高比,就能达到我们想要的效果了。

    我们现在只需要判断设备是小屏还是中大屏就可以了,这里借助GridRow栅格组件的断点能力,针对小屏和非小屏设备,设置不同的displayCount和aspectRatio就可以了,实现小源码如下。

    @ComponentV2
    struct Index {
      @Local breakPoint: string = 'unknown'
      @Local images: string[] = []
    
      @Computed
      get isSm(): boolean {
        return this.breakPoint === 'sm'
      }
    
      build() {
        Column() {
              GridRow({
                columns: 1,
                breakpoints: { reference: BreakpointsReference.WindowSize }
              }) {
                GridCol() {
                  Swiper() {
                    Repeat(this.images).each((data: Readonly<RepeatItem<string>>) => {
                      Image(data.item)
                    }).key((item) => item)
                  }
                  .width('100%')
                  .height('100%')
                  .loop(false)
                  .duration(1000)
                  .autoPlay(false)
                  .indicatorInteractive(true)
                  .itemSpace(this.isSm ? 0 : 32)
                  .displayCount(this.isSm ? 1 : 2)
                  .indicator(new DotIndicator().itemWidth(8)
                    .itemHeight(8)
                    .selectedItemWidth(12)
                    .selectedItemHeight(8)
                    .color($r('app.color.divider_color'))
                    .selectedColor($r('app.color.brand_color')))
                }
              }.width('100%').aspectRatio(this.isSm ? 2.5 : 4.5).onBreakpointChange((point) => {
                this.breakPoint = point
              })
            }.width('100%').justifyContent(FlexAlign.Start)
      }
    }
    

    在不同设备的显示效果如下。