Flutter开发指南(五):实现首页基础布局

一、项目结构

1.1 组件化设计

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

1.2 拆分首页组件

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

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

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

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

1.3 新建组件代码示例

HmCatrgory.dart代码

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代码

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代码

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代码

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代码

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代码

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代码

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代码

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代码

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代码

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 爆款推荐组件代码

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 Container(
      height: 200,
      color: Colors.blue,
      alignment: Alignment.center,
      child: Text('爆款推荐', style: TextStyle(color: Colors.white)),
    );
  }
}
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/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"组件来完成这个需求。

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/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());
  }
}
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 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代码

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代码

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

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