Flutter + OpenHarmony 网格布局:GridView 与 SliverGrid 在鸿蒙设备内容展示中的应用

个人主页:

文章目录

注:本文所有实践均基于 手机端场景,适用于 OpenHarmony 手机设备的应用开发。

前言

在 OpenHarmony 手机应用开发中,网格布局是展示图片、商品、功能入口等内容的常用方式。Flutter 提供了 GridViewSliverGrid 两种核心组件,分别适用于简单独立页面和复杂滚动联动场景。本文将从基础出发,系统介绍二者的作用、常见属性,并提供可直接运行的手机端代码示例。


基础组件------GridView 组件

作用/特点

GridView 是 Flutter 中用于构建二维滚动列表的基础组件。它适用于独立的网格页面,如相册、应用图标列表、商品橱窗等。其特点是:

  • 使用简单,开箱即用;
  • 支持垂直或水平滚动;
  • 可通过 gridDelegate 灵活控制列数与子项比例;
  • 默认使用 ListView 的底层机制,具备良好的性能表现。

常见属性

属性 类型 说明
scrollDirection Axis 滚动方向,默认 Axis.vertical
reverse bool 是否反转滚动方向
padding EdgeInsetsGeometry? 内边距
gridDelegate SliverGridDelegate 控制网格布局规则(必填)
children / itemBuilder + itemCount --- 子项数据源(推荐使用 builder 形式)
cacheExtent double 可视区域外预加载距离,提升滚动流畅度
physics ScrollPhysics? 滚动物理效果,手机默认为 ClampingScrollPhysics
shrinkWrap bool 是否包裹内容高度(嵌套时使用,否则影响性能)

⚠️ 手机端建议:始终使用 GridView.builder,避免一次性构建所有子项;若子项高度一致,可配合固定 childAspectRatio 提升性能。

代码示例

dart 复制代码
// grid_view_demo_phone.dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GridView 手机示例',
      home: Scaffold(
        appBar: AppBar(title: const Text('GridView - 商品列表')),
        body: GridView.builder(
          itemCount: 40,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,           // 手机常用 2 列
            childAspectRatio: 0.85,      // 宽略大于高
            mainAxisSpacing: 12,
            crossAxisSpacing: 12,
          ),
          cacheExtent: 600,
          itemBuilder: (context, index) {
            return _buildGridItem('商品 $index');
          },
        ),
      ),
    );
  }

  static Widget _buildGridItem(String title) {
    return Card(
      clipBehavior: Clip.hardEdge,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          AspectRatio(
            aspectRatio: 1.0,
            child: Container(color: Colors.grey[300]),
          ),
          Padding(
            padding: const EdgeInsets.all(8),
            child: Text(
              title,
              textAlign: TextAlign.center,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: const TextStyle(fontSize: 14),
            ),
          ),
        ],
      ),
    );
  }
}

运行界面:

基础组件------SliverGrid 组件

作用/特点

SliverGrid 不是独立 Widget,而是 CustomScrollView 中的一种 sliver(可滑动片段) 。它适用于需要与其他滚动元素联动的复杂页面,例如:

  • 顶部大图 Banner + 网格内容;
  • 可折叠的 AppBar + 网格列表;
  • 多类型混合滚动(文本 + 网格 + 分割线)。

其核心优势在于:统一滚动上下文,实现无缝联动与高性能滚动

常见属性

属性 类型 说明
delegate SliverChildDelegate 子项构建方式,常用 SliverChildBuilderDelegate
gridDelegate SliverGridDelegate GridView,控制列数与比例
key Key? 建议提供稳定 Key,避免重建
findChildIndexCallback ChildIndexGetter? 大数据集优化(配合 ValueKey 使用)

⚠️ 注意:SliverGrid 必须作为 CustomScrollView 的直接子项(sliver),不能单独使用。

代码示例

dart 复制代码
// sliver_grid_demo_phone.dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SliverGrid 手机示例',
      home: Scaffold(
        body: CustomScrollView(
          slivers: [
            const SliverAppBar(
              title: Text('应用中心'),
              pinned: true,
              expandedHeight: 180,
              flexibleSpace: FlexibleSpaceBar(
                background: DecoratedBox(
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    image: DecorationImage(
                      image: NetworkImage('https://picsum.photos/seed/banner/800/400'),  //顶部风景图,可替换
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              ),
            ),
            SliverGrid(
              delegate: SliverChildBuilderDelegate(
                (context, index) {
                  return _buildGridItem('App  $index');
                },
                childCount: 30,
              ),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,           // 手机图标常用 4 列
                childAspectRatio: 1.0,       // 正方形
                mainAxisSpacing: 10,         //控制网格横向间距
                crossAxisSpacing: 10,        //控制网格纵向间距
              ),
            ),
          ],
        ),
      ),
    );
  }

  static Widget _buildGridItem(String title) {
    return Card(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.apps_outlined, size: 32, color: Colors.grey[700]),
          const SizedBox(height: 4),
          Text(
            title,
            textAlign: TextAlign.center,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: const TextStyle(fontSize: 12),
          ),
        ],
      ),
    );
  }
}

运行界面:

面向 OpenHarmony 的工程建议

  1. 动态列数策略
    不要硬编码 crossAxisCount,应根据屏幕宽度计算:
dart 复制代码
int getColumnCount(double width) {
  if (width > 1200) return 6; // 智慧屏
  if (width > 800) return 4;  // 平板
  return 2;                   // 手机
}

2.图片加载必须优化

  • 使用 cached_network_image,并指定 width/height 或 fit,防止重排。

3.智慧屏交互适配

  • 增大点击区域(≥48dp)
  • 添加焦点高亮(focusColor 或边框)
  • 减少每屏信息量,避免视觉疲劳

4.性能监控常态化

  • 使用 Flutter DevTools 检查
  • Frame time(目标 <16ms)
  • Memory usage(滚动时平稳)
  • Widget rebuilds(网格项无意外重建)

结语

在 OpenHarmony 手机应用开发中,GridViewSliverGrid 各有其适用场景:前者简洁高效,适合独立内容展示;后者灵活强大,适用于需与 AppBar、Banner 等组件联动的复杂滚动页面。只要合理使用 builder 模式、固定子项比例、控制预加载范围,即可在手机端实现流畅、低内存占用的网格体验。

本文提供的两套完整示例代码,已覆盖日常开发中的主流需求,可直接集成至项目并快速迭代。掌握这两种网格布局方式,是构建高质量 Flutter 应用的重要基础。

🔜 下期预告 :《Flutter + OpenHarmony 用户输入框:TextField 与 InputDecoration 在多端表单中的交互设计》

我们将深入探讨如何在 OpenHarmony 手机上打造安全、易用、美观的输入体验,涵盖焦点管理、键盘适配、校验反馈与样式定制等实战技巧。敬请期待!

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui