Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用

news2024/11/25 20:20:02

在我们开发过程中经常会使用到悬浮菜单的使用,当我们滑动到指定位置后,菜单会自动悬浮。

实现效果如下(左为滑动前、右为滑动后):

上述便是通过NestedScrollView 、SliverAppBar实现的效果,通过两个控件我们便可以实现上述的效果。

废话不多说直接上代码,代码的实现原理会以注释的形式实现:

import 'package:aboxmini/view/home/room/room_device_page.dart';
import 'package:flutter/material.dart';
import '../../model/app_model.dart';

class HomeTabBar extends StatefulWidget {

  const HomeTabBar({super.key});

  @override
  State<HomeTabBar> createState() => _HomeTabBarState();
}

class _HomeTabBarState extends State<HomeTabBar> with TickerProviderStateMixin {
  /// 自定义的一个类,此类可获取屏幕宽度等
  final AppModel _appModel = AppModel.share();
  /// 设置 中间展示区域的高度
  final double _topHeight = 180 + AppModel.share().safeTop + kToolbarHeight;
  /// 分栏控制器
  late TabController tabController = TabController(length: 3, vsync: this);
  /// 分栏控制器每一个标题
  final _tabs = <String>["Tab 1", "Tab 2", "Tab 3"];

  @override
  void dispose() {
    tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabs.length,
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverOverlapAbsorber(
              handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              sliver: SliverAppBar(
                /// 取消系统导航左边按钮
                leading: Container(),
                /// 设置背景色
                backgroundColor: Colors.white,
                /// 设置左边按钮宽度
                leadingWidth: _appModel.width,
                centerTitle: false,
                pinned: true,
                floating: false,
                snap: false,
                primary: true,
                /// 设置分栏区域上面的高度
                expandedHeight: 230.0,
                elevation: 10,
                //是否显示阴影,直接取值innerBoxIsScrolled,展开不显示阴影,合并后会显示
                forceElevated: innerBoxIsScrolled,
                ///自定义导航和中间内容的展示
                flexibleSpace: _displayNavAndEnvInfo(),
                /// TabBar 分栏标题
                bottom: _addTabBar(),
              ),
            ),
          ];
        },
        /// 分栏展示的页面信息
        body: _addTabBarView(),
      ),
    );
  }

  /// 自定义导航和中间内容展示
  Widget _displayNavAndEnvInfo() {
    return Container(
      color: Colors.white,
      width: _appModel.width,
      height: _topHeight,
      child: Column(
        children: <Widget>[
          _addNav(),
          _displayEnvDevice(),
        ],
      ),
    );
  }

  /// 自定义导航 可随意定制
  Widget _addNav() {
    return SizedBox(
      width: _appModel.width,
      height: _appModel.safeTop + kToolbarHeight,
      child: Container(
        margin: EdgeInsets.only(top: _appModel.safeTop),
        height: kToolbarHeight,
        width: _appModel.width,
        alignment: Alignment.centerLeft,
        child: Row(
          children: <Widget>[
            GestureDetector(
              onTap: () {
                widget.z.toggle!();
              },
              child: Row(
                children: [
                  Container(
                    margin: const EdgeInsets.only(left: 12, right: 6),
                    child: const Icon(
                      Icons.menu,
                      size: 20,
                      color: Colors.red,
                    ),
                  ),
                  Text("${_appModel.currentDatum?.hostname ?? ""}"),
                ],
              ),
            ),
            Expanded(child: Container())
          ],
        ),
      ),
    );
  }

  /// 导航和TabBar中间展示的内容,可随意自定义
  Widget _displayEnvDevice() {
    return Container(
      color: Colors.white,
    );
  }

  /// TabBar 展示样式自定义,可以滚动并且居左展示
  PreferredSize _addTabBar() {
    return PreferredSize(
      /// 设置高度
      preferredSize: const Size.fromHeight(35),
      child: Align(
        /// 设置展示方式
        alignment: Alignment.centerLeft,
        /// TabBar选中、未选中样式
        child: TabBar(
          /// 是否允许滚动 
          isScrollable: true,
          unselectedLabelColor: Colors.black54,
          unselectedLabelStyle: const TextStyle(fontSize: 15),
          labelColor: Colors.blue,
          labelStyle:
              const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
          indicatorSize: TabBarIndicatorSize.label,
          tabs: _tabs.map((String name) => Tab(text: name)).toList(),
        ),
      ),
    );
  }

  /// TabBar 分栏下的各个页面
  Widget _addTabBarView() {
    return TabBarView(
      children: _tabs.map((String name) {
        // 分栏下的页面(可随意定义、也可以设置成Text等控件),实现方式还有其他方式
        return RoomDevicePage();
      }).toList(),
    );
  }
}

以上便是菜单悬浮的效果实现,注释写的很详细,直接粘贴复制即可实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1219616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTTPS加密为什么能保证网络安全?

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护用户的隐私和数据安全&#xff0c;许多网站都采用了HTTPS加密技术。那么&#xff0c;HTTPS加密为什么可以保证网络安全呢&#xff1f; 原因是HTTP协议采用的是数据明文传输方式。用户从客户端浏览器提交数据…

基于Java的鲜花商店的设计与实现,ssm+jsp,MySQL数据库,前台用户+后台管理,完美运行,有一万字论文

目录 演示视频 基本介绍 选题背景 系统结构 论文目录 系统截图 演示视频 基本介绍 基于Java的鲜花商店的设计与实现&#xff0c;ssmjsp&#xff0c;MySQL数据库&#xff0c;前台用户后台管理&#xff0c;完美运行&#xff0c;有一万字论文。 前台功能&#xff1a;注册登…

Python Web APP在宝塔发布

本地测试运行&#xff1a;uvicorn main:app --host 127.0.0.1 --port 8082 --reload 宝塔发布&#xff1a; 运行配置——>启动模式&#xff1a;worker_class uvicorn.workers.UvicornWorker

Windows安装Elasticsearch并结合内网穿透实现远程访问

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

Win10远程连接服务器失败,报错:出现了内部错误

背景&#xff1a;本地windows10专业版电脑远程Windows虚拟机报错&#xff0c;但实际检查控制台发现&#xff0c;虚拟机状态正常&#xff0c;只是本地远程连接莫名其妙断开&#xff0c;并报错出现了内部错误&#xff1a; 原因&#xff1a;win10客户端RDP兼容性的问题 解决方法&…

数据资产“入表”是不是红利?国企怎么认识?怎么利用?

毫无疑问&#xff0c;数字资产入表是红利。 数据资产入表意味着将数据资源作为企业资产进行确认和计量&#xff0c;解决了数据资源作为非物质资产未被充分认可和有效计量的问题&#xff0c;意味着数据完成了从自然资源到经济资产的跨越。上海数据交易所总经理汤奇峰此前表示&a…

代码混淆的原理是什么?常见代码混淆方法介绍

目录 一、代码混淆的原理 二、代码混淆的方法 三、常见的代码混淆方式 本文主要想你介绍代码混淆的原理&#xff0c;常见代码混淆方法&#xff0c;欢迎查阅~ 移动应用代码安全非常重要&#xff0c;代码逆向会导致代码逻辑被获取&#xff0c;进一步导致控制流被hook&#xff0…

忆联消费级SSD AH660:将用户体验推向新高度

自1989年IBM推出世界上第一款固态硬盘&#xff08;SSD&#xff09;以来&#xff0c;SSD在三十多年的时间中历经了多次技术革新和市场变革&#xff0c;早已成为个人电脑、汽车电子、数据中心、物联网终端等领域的主流存储产品&#xff0c;并广泛应用于各行各业&#xff0c;在202…

【LeetCode:2736. 最大和查询 | 贪心 + 二分 + 单调栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【学习笔记】Java安全之动态加载字节码

文章目录 什么是Java的字节码利用URLClassLoader加载远程class文件利用ClassLoader#defineClass直接加载字节码利用TemplatesImpl加载字节码利用BCEL ClassLoader加载字节码 最近在学习Phith0n师傅的知识星球的Java安全漫谈系列&#xff0c;随手记下笔记 什么是Java的字节码 J…

双向链表的知识点+例题

1.链表的种类 题中常考查以下两种&#xff1a; 上一讲我们学了无头单向非循环链表&#xff0c;这节&#xff0c;让我们看一下双向链表的操作吧~ 2基本操作 1&#xff0c;定义双向链表 2&#xff0c;创建一个节点 3&#xff0c;初始化双链表 4&#xff0c;尾插一个节点 5打印…

C语言判断素数(ZZULIOJ1057:素数判定)

题目描述 输入一个正整数n&#xff0c;判断n是否是素数&#xff0c;若n是素数&#xff0c;输出”Yes”,否则输出”No”。 注意&#xff1a;1不是素数。 输入&#xff1a;输入一个正整数n(n<1000) 输出&#xff1a;如果n是素数输出"Yes"&#xff0c;否则输出"…

Nuxt3框架全局引用外部JS/CSS文件的相关配置方法

全局引入外部文件方法&#xff1a; 找到根目录下的nuxt.config.ts配置文件&#xff1b;然后如上图所示&#xff0c;在defineNuxtConfig配置对象下app选项节点下&#xff0c;head对象中即可配置全局需要的JS或CSS文件&#xff1b; // https://nuxt.com/docs/api/configuration/…

Diagrams——制作短小精悍的流程图

今天为大家分享的是一款轻量级的流程图绘制软件——Diagrams。 以特定的图形符号加上说明&#xff0c;表示算法的图&#xff0c;称为流程图或框图。流程图是流经一个系统的信息流、观点流或部件流的图形代表。我们常用流程图来说明某一过程。 流程图使用一些标准符号代表某些类…

【Vue3 + webStorm】 求助,vite.config.js代理不生效

求助&#xff0c;vite.config.js代理不生效 上面为代理写法 上面为vue组件中,axios跳转写法 网页控制台一直跳转不到8080端口&#xff0c;请问是为什么&#xff1f;

标准库函数使用及源码

几个常规内存函数经常会使用的怀疑人生&#xff0c;现在整理一下 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 以下对内存函数进行整理。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、资源 MSDN网址 …

深度学习YOLO抽烟行为检测 - python opencv 计算机竞赛

文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习YOLO抽烟行为检测 该项目较为新颖&#xff0c;适合作为竞赛课…

2019年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

2019 年 1 月份管综初数真题 一、问题求解&#xff08;本大题共 5 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。 1、某车间计划 10 天完成一项任务&a…

小红书自动点赞评论脚本,可以群控多账号,按键精开源版代码分享

这个需要连接服务器&#xff0c;你可以在易语言配置一个服务端&#xff0c;然后设置好端口&#xff0c;脚本部署在模拟器或者云手机或者真机里面实现多账号点赞评论的效果&#xff0c;针对一个作品&#xff0c;按键精灵写的脚本&#xff0c;服务端的脚本需要自己写哈&#xff0…

ubuntu中/etc/rc.local和/etc/init.d/rc.local的区别是什么

在早期版本的Ubuntu中&#xff0c;通常会使用 /etc/rc.local 或 /etc/init.d/rc.local 文件执行在系统启动时需要运行的自定义脚本或命令。然而&#xff0c;随着Ubuntu的版本升级&#xff0c;这两者的使用方式有了一些变化。 /etc/rc.local&#xff1a; 功能&#xff1a; /etc/…