在这里插入图片描述
个人主页:

注:本文所有实践均基于 手机端场景,适用于 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 提升性能。

代码示例

// grid_view_demo_phone.dart
import 'package:flutter/material.dart';

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

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

  
  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),不能单独使用。

代码示例

// sliver_grid_demo_phone.dart
import 'package:flutter/material.dart';

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

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

  
  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,应根据屏幕宽度计算:
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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐