flutter开发实战-实现首页分类目录入口切换功能

这篇具有很好参考价值的文章主要介绍了flutter开发实战-实现首页分类目录入口切换功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

flutter开发实战-实现首页分类目录入口切换功能,移动开发,flutter开发实战,flutter,flutter,轮播图,swiper,分类入口,首页分类

在开发中经常遇到首页的分类入口,如美团的美食团购、打车等入口,左右切换还可以分页更多展示。

一、使用flutter_swiper_null_safety

在pubspec.yaml引入

  # 轮播图
  flutter_swiper_null_safety: ^1.0.2

二、实现swiper分页代码

由于我这里按照一页8条展示,两行四列展示格式。

当列表list传入的控件时候,一共的页数为

int getSwiperPageNumber() {
    int allLength = widget.list.length;
    int aPageNum = getSwiperOnePageNumber();
    if (allLength % aPageNum == 0) {
      return (allLength / aPageNum).toInt();
    }

    return (allLength / aPageNum).toInt() + 1;
  }

通过列表,一页数量计算每一页应该展示多少个按钮。

List getSwiperPagerItems(int pagerIndex) {
    List pagerItems = [];
    int allLength = widget.list.length;
    int aPageNum = getSwiperOnePageNumber();
    int start = pagerIndex * aPageNum;
    int end = (pagerIndex + 1) * aPageNum;
    if (end > allLength) {
      end = allLength;
    }
    pagerItems = widget.list.sublist(start, end);

    return pagerItems;
  }

一共pages的列表

int pagerNumber = getSwiperPageNumber();
    for (int index = 0; index < pagerNumber; index++) {
      CategorySwiperPagerItem swiperPagerItem = CategorySwiperPagerItem();
      swiperPagerItem.pagerIndex = index;
      swiperPagerItem.pagerItems = getSwiperPagerItems(index);
      swiperPagers.add(swiperPagerItem);
    }

通过使用flutter_swiper_null_safety来显示

Swiper(
        // 横向
        scrollDirection: Axis.horizontal,
        // 布局构建
        itemBuilder: (BuildContext context, int index) {
          CategorySwiperPagerItem swiperPagerItem = swiperPagers[index];
          return HomeCategoryPager(
            pagerIndex: swiperPagerItem.pagerIndex,
            pageItems: swiperPagerItem.pagerItems,
            width: itemWidth,
            height: itemHeight,
            containerHeight: showHeight,
            containerWidth: width,
          );
        },
        //条目个数
        itemCount: swiperPagers.length,
        // 自动翻页
        autoplay: false,
        // pagination: _buildSwiperPagination(),
        // pagination: _buildNumSwiperPagination(),
        //点击事件
        // onTap: (index) {
        //   LoggerManager().debug(" 点击 " + index.toString());
        // },
        // 相邻子条目视窗比例
        viewportFraction: 1,
        // 用户进行操作时停止自动翻页
        autoplayDisableOnInteraction: true,
        // 无限轮播
        loop: false,
        //当前条目的缩放比例
        scale: 1,
      ),

实现比较简单,

完整代码如下

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart';
import 'package:flutter_app_dfaceintl/config/resource_manager.dart';
import 'package:flutter_app_dfaceintl/utils/color_util.dart';
import 'package:flutter_app_dfaceintl/widget/common/show_gesture_container.dart';
import 'package:one_context/one_context.dart';
import 'package:flutter_app_dfaceintl/config/logger_manager.dart';

class CategorySwiperPagerItem {
  int pagerIndex = 0;
  List pagerItems = [];
}

class HomeCategoryWidget extends StatefulWidget {
  const HomeCategoryWidget({
    Key? key,
    required this.rowNumber,
    required this.numberOfPerRow,
    required this.list,
    required this.screenWidth,
  }) : super(key: key);

  // 多少行
  final int rowNumber;

  // 一行几个
  final int numberOfPerRow;

  final List list;

  final double screenWidth;

  
  State<HomeCategoryWidget> createState() => _HomeCategoryWidgetState();
}

class _HomeCategoryWidgetState extends State<HomeCategoryWidget> {
  double showHeight = 0.0;
  double containVPadding = 5.0;
  double containHPadding = 10.0;

  List<CategorySwiperPagerItem> swiperPagers = [];

  bool showPagination = false;

  
  void initState() {
    // TODO: implement initState

    double containerHeight = getContainerMaxHeight(widget.screenWidth);
    showHeight = containerHeight + 2 * containVPadding;

    int pagerNumber = getSwiperPageNumber();
    for (int index = 0; index < pagerNumber; index++) {
      CategorySwiperPagerItem swiperPagerItem = CategorySwiperPagerItem();
      swiperPagerItem.pagerIndex = index;
      swiperPagerItem.pagerItems = getSwiperPagerItems(index);
      swiperPagers.add(swiperPagerItem);
    }

    if (swiperPagers.length > 1) {
      showPagination = true;
    }

    super.initState();
  }

  
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    double width = widget.screenWidth;
    double itemWidth = (width - 2 * containHPadding) / widget.numberOfPerRow;
    double itemHeight = itemWidth;
    return Container(
      width: width,
      height: showHeight,
      margin: EdgeInsets.symmetric(vertical: 5.0),
      padding: EdgeInsets.symmetric(
        vertical: containVPadding,
        horizontal: containHPadding,
      ),
      color: Colors.white,
      child: Swiper(
        // 横向
        scrollDirection: Axis.horizontal,
        // 布局构建
        itemBuilder: (BuildContext context, int index) {
          CategorySwiperPagerItem swiperPagerItem = swiperPagers[index];
          return HomeCategoryPager(
            pagerIndex: swiperPagerItem.pagerIndex,
            pageItems: swiperPagerItem.pagerItems,
            width: itemWidth,
            height: itemHeight,
            containerHeight: showHeight,
            containerWidth: width,
          );
        },
        //条目个数
        itemCount: swiperPagers.length,
        // 自动翻页
        autoplay: false,
        // pagination: _buildSwiperPagination(),
        // pagination: _buildNumSwiperPagination(),
        //点击事件
        // onTap: (index) {
        //   LoggerManager().debug(" 点击 " + index.toString());
        // },
        // 相邻子条目视窗比例
        viewportFraction: 1,
        // 用户进行操作时停止自动翻页
        autoplayDisableOnInteraction: true,
        // 无限轮播
        loop: false,
        //当前条目的缩放比例
        scale: 1,
      ),
    );
  }

  int getSwiperOnePageNumber() {
    return widget.numberOfPerRow * widget.rowNumber;
  }

  int getSwiperPageNumber() {
    int allLength = widget.list.length;
    int aPageNum = getSwiperOnePageNumber();
    if (allLength % aPageNum == 0) {
      return (allLength / aPageNum).toInt();
    }

    return (allLength / aPageNum).toInt() + 1;
  }

  List getSwiperPagerItems(int pagerIndex) {
    List pagerItems = [];
    int allLength = widget.list.length;
    int aPageNum = getSwiperOnePageNumber();
    int start = pagerIndex * aPageNum;
    int end = (pagerIndex + 1) * aPageNum;
    if (end > allLength) {
      end = allLength;
    }
    pagerItems = widget.list.sublist(start, end);

    return pagerItems;
  }

  double getContainerMaxHeight(double screenWidth) {
    double width = screenWidth;
    double itemSize = (width - 2 * containHPadding) / widget.numberOfPerRow;
    double maxHeight = itemSize * widget.rowNumber;

    int allLength = widget.list.length;
    if (allLength <= widget.numberOfPerRow) {
      maxHeight = itemSize;
    }

    return maxHeight;
  }
}

class HomeCategoryPager extends StatelessWidget {
  const HomeCategoryPager({
    Key? key,
    required this.pagerIndex,
    required this.pageItems,
    required this.width,
    required this.height,
    this.containerWidth,
    this.containerHeight,
  }) : super(key: key);

  final int pagerIndex;

  final List pageItems;

  final double width;
  final double height;

  final double? containerWidth;
  final double? containerHeight;

  
  Widget build(BuildContext context) {
    return Container(
      width: containerWidth,
      height: containerHeight,
      child: Wrap(
        children: pageItems
            .map((e) => HomeCategoryItem(
                  width: width,
                  height: height,
                ))
            .toList(),
      ),
    );
  }
}

class HomeCategoryItem extends StatelessWidget {
  const HomeCategoryItem({
    Key? key,
    required this.width,
    required this.height,
  }) : super(key: key);

  final double width;
  final double height;

  
  Widget build(BuildContext context) {
    return ShowGestureContainer(
      padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
      width: width,
      height: height,
      highlightedColor: ColorUtil.hexColor(0xf0f0f0),
      onPressed: () {
        LoggerManager().debug("ShowGestureContainer");
      },
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          buildIcon(),
          Padding(
            padding: EdgeInsets.only(top: 5.0),
            child: buildTitle(),
          ),
        ],
      ),
    );
  }

  Widget buildTitle() {
    return Text(
      "栏目",
      textAlign: TextAlign.left,
      maxLines: 2,
      overflow: TextOverflow.ellipsis,
      softWrap: true,
      style: TextStyle(
        fontSize: 12,
        fontWeight: FontWeight.w500,
        fontStyle: FontStyle.normal,
        color: ColorUtil.hexColor(0x444444),
        decoration: TextDecoration.none,
      ),
    );
  }

  Widget buildIcon() {
    return Icon(
      Icons.access_alarm,
      size: 32.0,
      color: Colors.brown,
    );
  }
}

三、小结

flutter开发实战-实现首页分类目录入口切换功能。Swiper实现如美团的美食团购、打车等入口,左右切换还可以分页更多展示。

学习记录,每天不停进步。文章来源地址https://www.toymoban.com/news/detail-633431.html

到了这里,关于flutter开发实战-实现首页分类目录入口切换功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio App开发实战项目之实现淘宝电商App首页界面(附源码,可用于大作业参考)

    需要源码和图片集请点赞关注收藏后评论区留言或者私信~~~ 各家电商的App首页都是动感十足,页面元素丰富令人眼花缭乱,其中运用了Android的多种组合控件,可以说是App界面开发的集大成之作,下面我们也动手实现一个。 本次项目主要模仿淘宝App采用的技术,所以有底部标

    2024年02月03日
    浏览(15)
  • flutter开发实战-MethodChannel实现flutter与iOS双向通信

    flutter开发实战-MethodChannel实现flutter与iOS双向通信 最近开发中需要iOS与flutter实现通信,这里使用的MethodChannel 如果需要flutter与Android实现双向通信,请看 https://blog.csdn.net/gloryFlow/article/details/132218837 这部分与https://blog.csdn.net/gloryFlow/article/details/132218837中的一致,这里实现一下

    2024年02月13日
    浏览(12)
  • flutter开发实战-inappwebview实现flutter与Javascript方法调用

    flutter开发实战-inappwebview实现flutter与Javascript方法调用 在使用inappwebview时候,需要flutter端与JS进行交互,调用相应的方法,在inappwebview中的JavaScript Handlers。 要添加JavaScript Handlers,可以使用InAppWebViewController.addJavaScriptHandler方法,在该方法中定义handlerName和JavaScript端调用它时要

    2024年02月03日
    浏览(13)
  • flutter开发实战-事件总线EventBus实现

    flutter开发实战-事件总线EventBus实现 在开发中,经常会需要一个广播机制,用以跨Widget事件通知。 事件总线 实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色,可以通过事件总线来触发事件和监听事件。 实现eventBus 在工程的pubspec.yaml引入库 1.使用event_bus库 创建一

    2024年02月15日
    浏览(12)
  • flutter开发实战-MethodChannel实现flutter与原生Android双向通信

    flutter开发实战-MethodChannel实现flutter与原生Android双向通信 最近开发中需要原生Android与flutter实现通信,这里使用的MethodChannel MethodChannel:用于传递方法调用(method invocation)。 通道的客户端和宿主端通过传递给通道构造函数的通道名称进行连接 一个应用中所使用的所有通道名称

    2024年02月13日
    浏览(10)
  • Flutter 使用bloc模拟首页实现下拉刷新

    思考:这篇文章主要是记录bloc与下拉刷新功能的使用 本篇文章是延续上一篇文章中所包含的bloc和自定义http库的使用,使用发现在上一篇文章中对bloc的理解有些误区导致最后实现好几个方式都感觉不尽人意,最终尝试查看官方示例与个人示例进行比对后发现了问题所在, 下面

    2024年02月11日
    浏览(13)
  • flutter开发实战-dio文件下载实现

    flutter开发实战-dio文件下载实现 在开发中,需要下载文件,这里使用的是dio dio 是一个强大的 Dart HTTP 请求库,支持全局配置、Restful API、FormData、拦截器、 请求取消、Cookie 管理、文件上传/下载、超时以及自定义适配器等。 在工程中pubspec.yaml引入dio 我们对dio进行封装 文件下

    2024年02月11日
    浏览(16)
  • flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge

    flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge 在使用webview中,需要实现flutter与Javascript交互,在使用webview_flutter插件的时候,整理了一下webview与Javascript的交互JSBridge,具体可以查看 https://blog.csdn.net/gloryFlow/article/details/131683122 这里使用inappwebview插件来实现flutter与

    2024年02月08日
    浏览(16)
  • flutter开发实战-Universal Links配置及flutter微信分享实现

    flutter开发实战-Universal Links配置及flutter微信分享实现 在最近开发中碰到了需要实现微信分享,在iOS端需要配置UniversalLink,在分享使用fluwx插件来实现微信分享功能。 1.1、什么是UniversalLink Universal link 是Apple在iOS9推出的一种能够方便的通过传统HTTPS链接来启动APP的功能,可以使

    2024年01月19日
    浏览(25)
  • Flutter系列(十一)实现商城首页和商品详情页

    本文介绍了使用Flutter实现商城首页和商品详情页的过程,包括瀑布流插件的使用、页面跳转动画特效、顶部搜索框等组件的添加。商城首页展示了商品列表和点击跳转到商品详情页的功能,商品详情页包括商品信息、评价模块和底部固定栏等内容。详细代码和解决问题的方法也在文章中提供。

    2024年02月09日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包