鸿蒙Next实现瀑布流布局

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
实时计算 Flink 版,5000CU*H 3个月
简介: 在开始实现瀑布流布局前,需确保已安装好 DevEco Studio,且已配置好鸿蒙开发环境。打开 DevEco Studio,新建一个鸿蒙应用项目,选择合适的模板(如 Empty Feature Ability),设置项目名称、包名等信息,完成项目创建。

鸿蒙Next实现瀑布流布局 #鸿蒙影音娱乐类应用 #拍摄美化 #HarmonyOS

一、环境准备与项目创建

在开始实现瀑布流布局前,需确保已安装好 DevEco Studio,且已配置好鸿蒙开发环境。打开 DevEco Studio,新建一个鸿蒙应用项目,选择合适的模板(如 Empty Feature Ability),设置项目名称、包名等信息,完成项目创建。

二、布局设计思路

鸿蒙 Next 的瀑布流布局可以通过自定义组件结合 Column、Row 等容器组件实现。其核心思路是将数据分成若干列,每列独立滚动展示,且根据数据项高度动态调整布局,以达到类似瀑布自然流动的效果。

三、基础实现

创建一个自定义组件 MasonryLayout,接收图片数据数组作为参数,并根据列数将数据分配到不同列中展示:

@Component
export struct  MasonryLayout {
   
  @Prop data: string[];

  @State cols: number[] = Array.from<number>({
    length: 2 }).fill(0);

  build() {
   
    Row({
   }) {
   
      ForEach(this.cols, (_col: number, cIndex) => {
   
        Column({
     }) {
   
          ForEach(this.data, (item: string, i) => {
   
            if(i % this.cols.length === cIndex) {
   
              Image(item).width(`${
     100 / this.cols.length}%`);
            }
          })
        }
      })
    }.alignItems(VerticalAlign.Top)
  }
}

四、引用 MasonryLayout 瀑布流组件

build() {
   
  MasonryLayout({
   
    data: ["img1.png", "img2.png", "img3.png", "img4.png", "img5.png"],
  });
}

p1

五、优化与扩展

1. 响应式布局

通过 MediaQuery 组件根据屏幕宽度动态调整瀑布流的列数,以适配不同设备:

在 UIAbility 的 onWindowStageCreate 生命周期回调中,通过窗口对象获取启动时的应用窗口宽度并注册回调函数监听窗口尺寸变化。将窗口尺寸的长度单位由 px 换算为 vp 后,即可基于前文中介绍的规则得到当前断点值,此时可以使用状态变量记录当前的断点值方便后续使用

  • MainAbility.ts
import {
    window, display } from "@kit.ArkUI";
import {
    UIAbility } from "@kit.AbilityKit";

export default class MainAbility extends UIAbility {
   
  private windowObj?: window.Window;
  private col: number = 2;
  //...
  // 根据当前窗口尺寸更新断点
  private updateBreakpoint(windowWidth: number): void {
   
    // 将长度的单位由px换算为vp
    let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels;
    let col: number = this.col;
    if (windowWidthVp < 320) {
   
      // "xs";
      col = 1;
    } else if (windowWidthVp < 600) {
   
      // "sm";
      col = 2;
    } else if (windowWidthVp < 840) {
   
      // "md";
      col = 3;
    } else {
   
      // "lg";
      col = 4;
    }
    if (this.col !== col) {
   
      this.col = col;
    }
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
   
    windowStage.getMainWindow().then((windowObj) => {
   
      this.windowObj = windowObj;
      // 获取应用启动时的窗口尺寸
      this.updateBreakpoint(windowObj.getWindowProperties().windowRect.width);
      // 注册回调函数,监听窗口尺寸变化
      windowObj.on("windowSizeChange", (windowSize) => {
   
        this.updateBreakpoint(windowSize.width);
      });
    });
    // ...
  }

  //...
}
  • MasonryLayout.ets
interface IBpMapCol {
   
  xs: number;
  sm: number;
  md: number;
  lg: number;
}

const bpMapCol = new Map<string, number>();

bpMapCol.set('xs', 1)
bpMapCol.set('sm', 2)
bpMapCol.set('md', 3)
bpMapCol.set('lg', 4)

@Component
export struct  MasonryLayout {
   
  @StorageProp('currentBreakpoint') curBp: keyof IBpMapCol = 'sm';
  @Prop data: string[];

  @State cols: number[] = Array.from<number>({
    length: bpMapCol.get(this.curBp) || 2 }).fill(0);

  build() {
   
    Row({
   }) {
   
      ForEach(this.cols, (_col: number, cIndex) => {
   
        Column({
     }) {
   
          ForEach(this.data, (item: string, i) => {
   
            if(i % this.cols.length === cIndex) {
   
              Image(item).width(`${
     100 / this.cols.length}%`);
              Text(this.curBp)
            }
          })
        }
      })
    }.alignItems(VerticalAlign.Top)
  }
}

注:鸿蒙 next 中无法使用索引访问对象属性,如 const obj = { a: 1 } 无法使用 obj[a],这种情况可以用 Map

2. 动态加载数据

为了实现类似真实瀑布流不断加载新数据的效果,可以结合鸿蒙的 LazyForEach 组件,在滚动到列表底部时触发数据加载逻辑

六、网络权限

// config.json
{
   
  "module": {
   
    "reqPermissions": [
      {
   
        "name": "ohos.permission.INTERNET",
        "reason": "需要网络权限来加载图片"
      }
    ]
  }
}

七、常见问题与解决方案

1. 图片加载后布局跳动

  • 解决方案:使用预估高度占位,图片加载完成后更新高度

2. 大数据量性能问题

  • 解决方案:实现虚拟列表,只渲染可视区域内的元素

3. 滚动卡顿

  • 解决方案
    • 使用防抖/节流处理滚动事件
    • 避免在滚动回调中执行复杂计算
    • 使用鸿蒙的 Canvas 组件替代部分布局组件

4. 不同设备适配问题

  • 解决方案
    • 使用响应式布局动态调整列数
    • 基于设备类型设置不同的默认列数

八、最佳实践总结

  1. 优先使用固定高度:如果业务场景允许,尽量使用固定高度或宽高比,减少动态测量开销
  2. 合理实现懒加载:对于非首屏内容或图片资源,一定要实现懒加载
  3. 渐进式增强体验:先确保基础功能可用,再添加动画和交互效果
  4. 测试与优化:在不同设备上测试性能表现,针对卡顿问题进行专项优化
  5. 遵循鸿蒙设计规范:保持与鸿蒙系统一致的视觉风格和交互体验
目录
相关文章
|
8天前
|
API 开发者
鸿蒙NEXT上传图片功能PhotoViewPicker核心功能解析
`PhotoViewPicker` 是鸿蒙系统中用于媒体资源选择的核心组件,通过它可以便捷地实现图片、视频等媒体文件的选择功能。下面从基本用法、参数配置到高级应用进行全面解析:
35 1
|
17天前
|
数据安全/隐私保护
贡献 OpenHarmony 库关键配置 #自研框架#ArkUI-X#三方框架#OpenHarmony#HarmonyOS
# 贡献 OpenHarmony 库关键配置 #自研框架#ArkUI-X#三方框架#OpenHarmony#HarmonyOS
58 11
|
26天前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
385 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
解决使用-webkit-app-region后鼠标点击失败的问题
在开发中,如果我们想要实现窗口拖动的功能,可以通过给相应的元素设置 -webkit-app-region: drag 属性来实现。然而,这样做会引发一些问题,包括当前元素权级高于其他元素、无法触发鼠标相关事件以及双击全屏和还原窗口大小功能失效等。本文将介绍如何解决这些问题,实现既能拖动窗口又不影响窗口内部元素的需求。
1860 0
|
存储 移动开发 Android开发
HarmonyOS应用开发者高级认证(88分答案)
HarmonyOS应用开发者高级认证(88分答案)
3406 0
|
4天前
|
数据安全/隐私保护 Windows
Win10 22H2企业级纯净部署|UEFI引导+磁盘分区(含官方镜像文件)
本教程详细介绍了如何安装纯净版Windows 10系统。首先,下载官方镜像文件(win_10_x64.iso),包含家庭版与专业版。接着,格式化U盘为NTFS文件系统,并使用Rufus软件将镜像写入U盘。根据电脑品牌选择正确的快捷键进入U盘启动模式,如联想F12、惠普F9等。启动后,按提示设置语言、版本、分区等信息,完成安装需15-30分钟。最后配置用户名、密码及安全问题即可。适合新手操作,助你轻松装机!
Win10 22H2企业级纯净部署|UEFI引导+磁盘分区(含官方镜像文件)
|
30天前
|
人工智能 负载均衡 数据可视化
10分钟上手全球开源模型冠军 Qwen3
阿里通义千问Qwen3在最新全球AI基准测试中智能水平位列全球前五,开源第一,且成本优势显著,推理成本仅为DeepSeek-R1的1/3、Claude 3.7的1/20。Qwen3支持119种语言,具备强大的代码和数学能力,同时提供思考与非思考两种模式无缝切换,适合复杂与简单任务。通过阿里云百炼平台,用户可在10分钟内快速搭建Qwen3模型服务,结合Cherry Studio客户端实现便捷交互。本文详细介绍了Qwen3的部署、体验及工具调用能力,帮助用户轻松上手。
634 78
|
4天前
|
传感器 人工智能 自然语言处理
比亚迪座舱接入通义大模型,未来将联合打造更多AI智能座舱场景
比亚迪与阿里云深度合作,将通义大模型应用于智能座舱和营销服务。通过通义万相,腾势推出“AI壁纸”功能;借助通义星尘,实现“心理伴聊”等情感陪伴场景。阿里云Mobile-Agent智能体落地比亚迪座舱,支持复杂语音操作,如查询淘宝物流、订火车票等。该方案基于全视觉解决技术,具有强泛化能力,未来双方将持续拓展更多AI应用。
|
4天前
|
人工智能 数据可视化 物联网
工业4.0数字孪生新引擎:星图云开发者平台全景评测
在“中国制造2025”战略推动下,工业互联网平台迎来爆发式增长,但也面临数据孤岛、分析能力不足等技术瓶颈。中科星图推出的“星图云开发者平台”通过低代码开发、多源数据融合和智能分析等创新技术,解决了工业数字化转型中的关键问题。该平台不仅支持三维可视化渲染和遥感数据分析,还兼容多种主流GIS标准协议,实现空天地一体化数据融合。其丰富的行业模板覆盖能源、园区、水务等领域,大幅降低开发门槛。评测显示,相比传统低代码平台,星图云在3D建模、GIS支持和IoT设备接入等方面表现突出,为工业数字孪生提供了全面解决方案,助力智能化升级与跨行业应用拓展。
|
30天前
|
消息中间件 运维 监控
加一个JVM参数,让系统可用率从95%提高到99.995%
本文针对一个高并发(10W+ QPS)、低延迟(毫秒级返回)的系统因内存索引切换导致的不稳定问题,深入分析并优化了JVM参数配置。通过定位问题根源为GC压力大,尝试了多种优化手段:调整MaxTenuringThreshold、InitialTenuringThreshold、AlwaysTenure等参数让索引尽早晋升到老年代;探索PretenureSizeThreshold和G1HeapRegionSize实现索引直接分配到老年代;加速索引复制过程以及升级至JDK11使用ZGC。
366 82
加一个JVM参数,让系统可用率从95%提高到99.995%