flutter 的 overlay组件示例10

这段代码通过合理运用 Flutter 的各种组件、控制器以及覆盖层等相关技术,实现了根据页面滚动情况动态显示和隐藏悬浮按钮,并实现了点击悬浮按钮使页面滚动回顶部的功能。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ScrollController _scrollController = ScrollController();
  OverlayEntry? _floatingButtonOverlayEntry;

  
  void initState() {
    super.initState();
    _scrollController.addListener(_scrollListener);
  }

  
  void dispose() {
    _scrollController.removeListener(_scrollListener);
    _scrollController.dispose();
    super.dispose();
  }

  void _scrollListener() {
    if (_scrollController.offset > 100 && _floatingButtonOverlayEntry == null) {
      // 显示悬浮按钮
      _showFloatingButton();
    } else if (_scrollController.offset <= 100 &&
        _floatingButtonOverlayEntry != null) {
      // 隐藏悬浮按钮
      _hideFloatingButton();
    }
  }

  void _showFloatingButton() {
    _floatingButtonOverlayEntry = OverlayEntry(
      builder: (context) {
        return Positioned(
          right: 20.0,
          bottom: 20.0,
          child: FloatingActionButton(
            onPressed: _scrollToTop,
            child: Icon(Icons.arrow_upward),
          ),
        );
      },
    );
    Overlay.of(context)!.insert(_floatingButtonOverlayEntry!);
  }

  void _hideFloatingButton() {
    _floatingButtonOverlayEntry!.remove();
    _floatingButtonOverlayEntry = null;
  }

  void _scrollToTop() {
    _scrollController.animateTo(
      0,
      duration: Duration(milliseconds: 500),
      curve: Curves.easeInOut,
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Floating Button Example')),
      body: NotificationListener<ScrollNotification>(
        onNotification: (scrollNotification) {
          // 可以在这里处理滚动通知
          return true;
        },
        child: ListView.builder(
          controller: _scrollController,
          itemCount: 100,
          itemBuilder: (context, index) {
            return ListTile(title: Text('Item $index'));
          },
        ),
      ),
    );
  }
}

以下是分析内容:

  1. 整体功能
    实现了一个页面功能,当页面内容向下滚动超过 100 像素时,会在页面右下角显示一个悬浮的向上箭头按钮,点击该按钮可使页面快速滚动回到顶部;当页面滚动回到距离顶部 100 像素以内时,悬浮按钮会隐藏。

  2. 导入库
    通过 import ‘package:flutter/material.dart’; 导入 Flutter 核心库,用于获取构建应用所需的 UI 组件、样式及相关功能等。

  3. 应用入口点(main 函数)
    main 函数作为 Flutter 应用入口,调用 runApp 并传入 MyApp 类实例来启动应用。

  4. MyApp 类
    MyApp 继承自 StatelessWidget,为无状态组件,其 build 方法返回 MaterialApp 实例并指定首页为 MyHomePage 类实例,UI 创建后不因内部状态改变重新渲染。

  5. MyHomePage 类
    继承关系与状态管理:
    MyHomePage 继承自 StatefulWidget,表明页面 UI 可能随内部状态变化重新渲染,通过 createState 方法创建并返回对应的 _MyHomePageState 实例管理页面状态。

_MyHomePageState 类相关操作:
状态管理相关变量和控制器:
定义一个 ScrollController,用于控制页面滚动相关操作,比如获取当前滚动偏移量等。
一个 OverlayEntry 类型变量,用于管理悬浮按钮在页面上的显示和隐藏状态,初始值为 null。

生命周期方法:
在页面初始化时调用的方法中,给 ScrollController 添加滚动监听器,以便在滚动事件发生时处理。
在页面销毁时调用的方法会移除之前添加给 ScrollController 的滚动监听器,并释放其占用的资源。

滚动监听器方法:
根据 ScrollController 的当前滚动偏移量以及 OverlayEntry 类型变量的状态来决定是显示还是隐藏悬浮按钮。当滚动偏移量大于 100 像素且该变量为 null(悬浮按钮未显示)时,调用相关方法显示悬浮按钮;当滚动偏移量小于等于 100 像素且该变量不为 null(悬浮按钮已显示)时,调用相关方法隐藏悬浮按钮。

显示悬浮按钮方法:
先创建一个 OverlayEntry,其构建函数返回一个组件用于将悬浮操作按钮定位在页面右下角,设置按钮图标为向上箭头,点击可调用滚动到顶部的方法。
然后将创建好的 OverlayEntry 插入到页面覆盖层中,使悬浮按钮显示在页面上。

隐藏悬浮按钮方法:
直接调用 OverlayEntry 的 remove 方法移除之前插入的 OverlayEntry,并将该变量重置为 null,使悬浮按钮从页面消失。

滚动到顶部方法:
使用 ScrollController 的相关方法,让页面滚动条在 500 毫秒内以特定曲线动画效果滚动到顶部(偏移量为 0)。

构建 UI 方法:
返回一个 Scaffold 组件,包含 appBar(设置标题)和 body(主体内容)部分。
appBar 标题设为 Floating Button Example。
body 部分用 NotificationListener 来监听滚动通知,其内部包裹着一个 ListView.builder,通过相关控制器控制滚动,设置列表项目数量,每个项目通过相关构建方法构建为特定格式显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值