一、项目结构

1.1 组件化设计

何为组件化设计?简单来说,就是把一个页面的内容拆分成多个部分,由多个部分组成一个完整的页面。比如,我们要做的首页,拆分为了五个文件,再由这五个文件组成我们的首页。

1.2 拆分首页组件

在lib/components下新建Home文件夹,分别新建HmSlider.dart文件,HmCategory.dart文件,HmSuggestion.dart文件,HmHot.dart文件,HmmoreList.dart文件

这里输入"stful"即可一键生成代码,然后再命名该文件。

报错是因为没有导入material的包,鼠标悬浮在StatefulWidget,选择蓝色部分导入即可或者直接加入下面这行代码

import 'package:flutter/material.dart';

1.3 新建组件代码示例

HmCatrgory.dart代码

import 'package:flutter/material.dart';

class HmCategory extends StatefulWidget {
  const HmCategory({super.key});

  @override
  State<HmCategory> createState() => _HmCategoryState();
}

class _HmCategoryState extends State<HmCategory> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

HmHot.dart代码

import 'package:flutter/material.dart';

class HmHot extends StatefulWidget {
  const HmHot({super.key});

  @override
  State<HmHot> createState() => _HmHotState();
}

class _HmHotState extends State<HmHot> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

HmMoreList.dart代码

import 'package:flutter/material.dart';

class HmMorelist extends StatefulWidget {
  const HmMorelist({super.key});

  @override
  State<HmMorelist> createState() => _HmMorelistState();
}

class _HmMorelistState extends State<HmMorelist> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

HmSlider.dart代码

import 'package:flutter/material.dart';
class HmSlider extends StatefulWidget {
  const HmSlider({super.key});

  @override
  State<HmSlider> createState() => _HmSliderState();
}

class _HmSliderState extends State<HmSlider> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

HmSuggestion.dart代码

import 'package:flutter/material.dart';
class HmSuggestion extends StatefulWidget {
  const HmSuggestion({super.key});

  @override
  State<HmSuggestion> createState() => _HmSuggestionState();
}

class _HmSuggestionState extends State<HmSuggestion> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

二、编写组件对应代码

以下代码如果想跟文章一步一步探索,只需要书写完成后,只需要在"lib/pages/home/index.dart"

代码中导入对应的组件即可。如果不想跟着文章来,大家也无需担心,在最后会给出修改后完整的代码。

2.1 轮播图组件代码

HmSlider.dart代码

import 'package:flutter/material.dart';

class HmSlider extends StatefulWidget {
  const HmSlider({super.key});

  @override
  State<HmSlider> createState() => _HmSliderState();
}

class _HmSliderState extends State<HmSlider> {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.blue,
        height: 300,
        alignment: Alignment.center,
        child:
            Text('轮播图', style: TextStyle(color: Colors.white, fontSize: 20)));
  }
}

Home/index.dart代码

import 'package:flutter/cupertino.dart';
import 'package:qing_mall/components/Home/HmSlider.dart';

class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  //获取滚动容器的内容

  List<Widget> _getScrollChildren() {
    return [
      //包裹普通widget的sliver家族的组件内容
      SliverToBoxAdapter(child: HmSlider()),//轮播图组件
    ];
  }

  @override
  Widget build(BuildContext context) {
    //CustomScrollview要求:必须是sliver家族的内容
    return CustomScrollView(slivers: _getScrollChildren());
  }
}

完成上述代码后运行到鸿蒙模拟器效果如下,可以看到轮播图的轮廓已经出来了。接下来我们继续编写其他组件的代码。

2.2 分类组件代码

HmCategory.dart代码

import 'package:flutter/material.dart';

class HmCategory extends StatefulWidget {
  const HmCategory({super.key});

  @override
  State<HmCategory> createState() => _HmCategoryState();
}

class _HmCategoryState extends State<HmCategory> {
  @override
  Widget build(BuildContext context) {
    //返回一个横向滚动的组件,但是得设置高度。但是ListView自身不能设置高度.能设置高度的只有Container和SizeBox
    return SizedBox(
      height: 100,
      child: ListView.builder(
          scrollDirection: Axis.horizontal,
          itemCount: 10,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              alignment: Alignment.center,
              width: 80,
              height: 100,
              color: Colors.blue,
              child: Text("分类$index", style: TextStyle(color: Colors.white)),
              margin: EdgeInsets.symmetric(horizontal: 10),
            );
          }),
    );
  }
}

完成上述代码后运行到鸿蒙模拟器效果如下,可以看到分类的轮廓已经出来了。

2.3 推荐组件代码

HmSuggestion.dart代码

import 'package:flutter/material.dart';

class HmSuggestion extends StatefulWidget {
  const HmSuggestion({super.key});

  @override
  State<HmSuggestion> createState() => _HmSuggestionState();
}

class _HmSuggestionState extends State<HmSuggestion> {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.blue,
        alignment: Alignment.center,
        height: 300,
        child: Text(
          "推荐",
          style: TextStyle(color: Colors.white),
        ));
  }
}

Main/index.dart代码

import 'package:flutter/cupertino.dart';
import 'package:qing_mall/components/Home/HmCategory.dart';
import 'package:qing_mall/components/Home/HmSlider.dart';
import 'package:qing_mall/components/Home/HmSuggestion.dart';

class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  //获取滚动容器的内容

  List<Widget> _getScrollChildren() {
    return [
      //包裹普通widget的sliver家族的组件内容
      SliverToBoxAdapter(child: HmSlider()),//轮播图组件
      //放置分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      //SliverGrid SliverList指南纵向排列
      SliverToBoxAdapter(child: HmCategory()), //分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      SliverToBoxAdapter(child: HmSuggestion()), //推荐组件


      SliverToBoxAdapter(child: Flex(
        direction: Axis.horizontal,
        children: [
          
        ],
      )),
    ];
  }

  @override
  Widget build(BuildContext context) {
    //CustomScrollview要求:必须是sliver家族的内容
    return CustomScrollView(slivers: _getScrollChildren());
  }
}

2.4 爆款推荐组件代码

import 'package:flutter/material.dart';

class HmHot extends StatefulWidget {
  const HmHot({super.key});

  @override
  State<HmHot> createState() => _HmHotState();
}

class _HmHotState extends State<HmHot> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      color: Colors.blue,
      alignment: Alignment.center,
      child: Text('爆款推荐', style: TextStyle(color: Colors.white)),
    );
  }
}
import 'package:flutter/cupertino.dart';
import 'package:qing_mall/components/Home/HmCategory.dart';
import 'package:qing_mall/components/Home/HmHot.dart';
import 'package:qing_mall/components/Home/HmSlider.dart';
import 'package:qing_mall/components/Home/HmSuggestion.dart';

class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  //获取滚动容器的内容

  List<Widget> _getScrollChildren() {
    return [
      //包裹普通widget的sliver家族的组件内容
      SliverToBoxAdapter(child: HmSlider()),//轮播图组件
      //放置分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      //SliverGrid SliverList指南纵向排列
      SliverToBoxAdapter(child: HmCategory()), //分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      SliverToBoxAdapter(child: HmSuggestion()), //推荐组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),


      //Flex和Expanded配合起来可以均分比例
      SliverToBoxAdapter(child: Flex(
        direction: Axis.horizontal,
        children: [
          Expanded(child: HmHot()),
          SizedBox(width: 10,),
          Expanded(child: HmHot()),

        ],
      )),
    ];
  }

  @override
  Widget build(BuildContext context) {
    //CustomScrollview要求:必须是sliver家族的内容
    return CustomScrollView(slivers: _getScrollChildren());
  }
}

此时我们发现推荐和爆款间距的部分没有内边距,看起来不太好看,一般电商平台App的这部分都是有间距的,所以我们使用"Padding"组件来完成这个需求。

import 'package:flutter/cupertino.dart';
import 'package:qing_mall/components/Home/HmCategory.dart';
import 'package:qing_mall/components/Home/HmHot.dart';
import 'package:qing_mall/components/Home/HmSlider.dart';
import 'package:qing_mall/components/Home/HmSuggestion.dart';

class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  //获取滚动容器的内容

  List<Widget> _getScrollChildren() {
    return [
      //包裹普通widget的sliver家族的组件内容
      SliverToBoxAdapter(child: HmSlider()), //轮播图组件
      //放置分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      //SliverGrid SliverList指南纵向排列
      SliverToBoxAdapter(child: HmCategory()), //分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      SliverToBoxAdapter(child: HmSuggestion()), //推荐组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),

      //Flex和Expanded配合起来可以均分比例
      SliverToBoxAdapter(
        child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 10),
            child: Flex(
              direction: Axis.horizontal,
              children: [
                Expanded(child: HmHot()),
                SizedBox(
                  width: 10,
                ),
                Expanded(child: HmHot()),
              ],
            )),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    //CustomScrollview要求:必须是sliver家族的内容
    return CustomScrollView(slivers: _getScrollChildren());
  }
}
import 'package:flutter/material.dart';

class HmSuggestion extends StatefulWidget {
  const HmSuggestion({super.key});

  @override
  State<HmSuggestion> createState() => _HmSuggestionState();
}

class _HmSuggestionState extends State<HmSuggestion> {
  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: EdgeInsets.symmetric(horizontal: 10),
        child: Container(
            color: Colors.blue,
            alignment: Alignment.center,
            height: 300,
            child: Text(
              "推荐",
              style: TextStyle(color: Colors.white),
            )));
  }
}

加入"Padding 组件"后可以看见,推荐和爆款推荐已经有内边距了

2.5 商品组件代码

HmMoreList.dart代码

import 'package:flutter/material.dart';

class HmMorelist extends StatefulWidget {
  const HmMorelist({super.key});

  @override
  State<HmMorelist> createState() => _HmMorelistState();
}

class _HmMorelistState extends State<HmMorelist> {
  @override
  Widget build(BuildContext context) {
    //必须是Sliver家族的组件
    return SliverGrid.builder(gridDelegate:
    //网格是两列
    SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10),
        itemBuilder: (BuildContext context, int index) {
          return Container(
            child: Text("商品", style: TextStyle(color: Colors.white),),
            color: Colors.blue,
            alignment: Alignment.center,
          );
        });
  }
}

lib/pages/Home/index.dart代码

import 'package:flutter/cupertino.dart';
import 'package:qing_mall/components/Home/HmCategory.dart';
import 'package:qing_mall/components/Home/HmHot.dart';
import 'package:qing_mall/components/Home/HmMoreList.dart';
import 'package:qing_mall/components/Home/HmSlider.dart';
import 'package:qing_mall/components/Home/HmSuggestion.dart';

class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  //获取滚动容器的内容

  List<Widget> _getScrollChildren() {
    return [
      //包裹普通widget的sliver家族的组件内容
      SliverToBoxAdapter(child: HmSlider()), //轮播图组件
      //放置分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      //SliverGrid SliverList指南纵向排列
      SliverToBoxAdapter(child: HmCategory()), //分类组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      SliverToBoxAdapter(child: HmSuggestion()), //推荐组件
      SliverToBoxAdapter(child: SizedBox(height: 10)),

      //Flex和Expanded配合起来可以均分比例
      SliverToBoxAdapter(
        child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 10),
            child: Flex(
              direction: Axis.horizontal,
              children: [
                Expanded(child: HmHot()),
                SizedBox(
                  width: 10,
                ),
                Expanded(child: HmHot()),
              ],
            )),
      ),
      SliverToBoxAdapter(child: SizedBox(height: 10)),
      HmMorelist(),//无限滚动列表
    ];
  }

  @override
  Widget build(BuildContext context) {
    //CustomScrollview要求:必须是sliver家族的内容
    return CustomScrollView(slivers: _getScrollChildren());
  }
}

三、Git上传代码

每次上传代码,基本的步骤基本就是

(1)git add .【提交自己的代码到暂存区】

(2)git commit -m "讲自己干了什么内容" 【讲自己这次干了啥】

(3)git push 【推送到自己的仓库】

如果文章中的代码有问题,大家可以直接看项目的地址,自己克隆源码进行修改,仓库如下:

青商城 - AtomGithttps://AtomGit.com/Deng666/shangcheng

四、结语

通过本文我们完成了组件化的设计。我们将首页拆分为多个独立模块(轮播图、分类、推荐等),每个组件具备独立状态管理能力,使用StatefulWidget实现动态交互。这种架构模式提升了代码复用性和维护效率,符合Flutter声明式UI的开发理念。后续我们将调用API接口渲染到首页的UI上,展示真实的数据。

感谢大家的观看,如果本文章对你有帮助,可以点赞支持一下。如果有疑问,可以在评论区留言,看到会回答。您的点赞将是我最大的动力。

最后

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

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐