【Flutter】监听RefreshIndicator下拉到可刷新位置时震动

在这里插入图片描述

需求

下拉到可刷新位置时震动

flutter version: 3.22.2

仅在该版本测试,其他版本未测试。

方法

各有优缺点,本文使用方案3,建议使用方案2。

1.修改SDK中的RefreshIndicator(pass)

2.Copy RefreshIndicator,在原控件上加逻辑(更稳定,推荐)

3.监听ScrollNotification(更灵活,本文使用)

How Use

ListenReadyRefresh(
  //到达位置时回调
    ready: () async => Vibration.vibrate(
        amplitude: await Vibration.hasAmplitudeControl() == true ? 1 : -1,
        duration: 50),
    child: RefreshIndicator(
        triggerMode: RefreshIndicatorTriggerMode.anywhere,
        child:....))

ListenReadyRefresh Widget 实现

通过ScrollNotification计算下,复制RefreshIndicator计算逻辑,到达位置时触发回调;

import 'dart:ui';

import 'package:flutter/cupertino.dart';

class ListenReadyRefresh extends StatefulWidget {
  final Widget child;

  final Function ready;
  const ListenReadyRefresh({super.key, required this.child, required this.ready});

  
  State<ListenReadyRefresh> createState() =>
      _ListenReadyRefreshState();
}

class _ListenReadyRefreshState
    extends State<ListenReadyRefresh> {
  var _dragOffset = 0.0;
  var vibration = true;

  var canStart = false;


  
  Widget build(BuildContext context) {
    return NotificationListener<ScrollNotification>(
        onNotification: handleScrollNotification, child: widget.child);
  }

  bool handleScrollNotification(ScrollNotification notification) {
    if((((notification is ScrollStartNotification && notification.dragDetails != null)
        || (notification is ScrollUpdateNotification && notification.dragDetails != null))
        && (( notification.metrics.axisDirection == AxisDirection.up && notification.metrics.extentAfter == 0.0)
            || (notification.metrics.axisDirection == AxisDirection.down && notification.metrics.extentBefore == 0.0)) && _dragOffset==0)){
      canStart = true;
      return false;
    }
    if(!canStart){
      return false;
    }
    if (notification is ScrollEndNotification) {
      _dragOffset = 0.0;
      vibration = true;
      canStart = false;
    }
    double? scrollDelta;
    if (notification is OverscrollNotification) {
      scrollDelta = notification.overscroll!;
    } else if (notification is ScrollUpdateNotification) {
      scrollDelta = notification.scrollDelta!;
    }
    if (scrollDelta != null && vibration == true) {
      if (notification.metrics.axisDirection == AxisDirection.down) {
        _dragOffset = _dragOffset - scrollDelta;
      } else if (notification.metrics.axisDirection == AxisDirection.up) {
        _dragOffset = _dragOffset + scrollDelta;
      }
      double newValue =
          _dragOffset / (notification.metrics.viewportDimension * 0.25);
      newValue = clampDouble(newValue, 0.0, 1.0);
      if(newValue == 1 && vibration){
        vibration =false;
        widget.ready();
      }
    }
    return false;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值