Fluter InteractiveViewer 与ScrollView滑动冲突问题解决

InteractiveViewer是Flutter比较少用到的组件,它的作用是能够通过手势放大和缩小某个Widget。 某些需求,比如报表需要可以通过手势去放大和缩小,报表本身又是可以上下滑动的。这个时候可能用InteractiveViewer包裹ScrollView。

但由于两个组件都是手势操作,而且ScrollView的优先级会更高,就造成InteractiveViewer在纵向上缩放不灵敏。

现在想到一个解决的笨办法就是通过判断手势的个数去禁用ScrollView的滑动。

以下为实现代码:

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

//解决上下滑动与放大缩手势冲突问题,判断多点触控,如果大于一点则禁用滑动
class InteractiveScrollView extends StatefulWidget {

    final List<Widget> slivers;
    final double minScale;
    final double maxScale;

    const InteractiveScrollView(
    {super.key, required this.slivers, this.minScale = 1, this.maxScale = 5});

    @override
    State<InteractiveScrollView> createState() => _InteractiveScrollViewState();
}


class _InteractiveScrollViewState extends State<InteractiveScrollView> {

    int pointerCount = 0;
    bool scrollable = true;

    void checkScrollable() {
        if (pointerCount >= 2) {
            if (scrollable) {
                setState(() {
                    scrollable = false;
                });
            }
        } else {
            if (!scrollable) {
                setState(() {
                    scrollable = true;
                });
            }
        }
    }

    void _onPointerDown(PointerDownEvent details) {
        pointerCount++;
        checkScrollable();
    }

    void _onPointerCancel(PointerCancelEvent details) {
        pointerCount = 0;
        checkScrollable();
    }

    void _onPointerUp(PointerUpEvent details) {
        pointerCount--;
        checkScrollable();
    }

    @override
    Widget build(BuildContext context) {
        return Listener(
            onPointerDown: _onPointerDown,
            onPointerUp: _onPointerUp,
            onPointerCancel: _onPointerCancel,
            child: InteractiveViewer(
                minScale: widget.minScale,
                maxScale: widget.maxScale,
                child: CustomScrollView(
                    physics: scrollable
                        ? const ClampingScrollPhysics()
                        : const NeverScrollableScrollPhysics(),
                    slivers: widget.slivers
                )
           )
       );
    }
    
    @override
    void didUpdateWidget(covariant InteractiveScrollView oldWidget) {
        super.didUpdateWidget(oldWidget);
        if (oldWidget.maxScale != widget.maxScale ||
            oldWidget.minScale != widget.minScale) {
            setState(() {});
        }
    }
}

上面代码是将InteractiveViewer与CustomScrollView集合,实际上可以是任何滑动组件。 实现的原理也很简单粗暴,就是通过监听手势按下的数量pointerCount,如果大于2则将 CustomScrollView的physics属性设置为NeverScrollableScrollPhysics。

这种实现方式虽然能够达到需求,但感觉不够优雅,或许可以通过重写ScrollPhysics的方式达到目的。 如果有更好的实现方式可以在下方留言。

相关推荐
小雨下雨的雨15 分钟前
Flutter 框架跨平台鸿蒙开发 —— Flex 控件之响应式弹性布局
flutter·ui·华为·harmonyos·鸿蒙系统
cn_mengbei18 分钟前
Flutter for OpenHarmony 实战:CheckboxListTile 复选框列表项详解
flutter
cn_mengbei31 分钟前
Flutter for OpenHarmony 实战:Switch 开关按钮详解
flutter
奋斗的小青年!!32 分钟前
OpenHarmony Flutter实战:打造高性能订单确认流程步骤条
flutter·harmonyos·鸿蒙
Coder_Boy_39 分钟前
Flutter基础介绍-跨平台移动应用开发框架
spring boot·flutter
cn_mengbei1 小时前
Flutter for OpenHarmony 实战:Slider 滑块控件详解
flutter
行者961 小时前
Flutter跨平台骨架屏组件在鸿蒙系统上的实践与优化
flutter·harmonyos·鸿蒙
奋斗的小青年!!1 小时前
Flutter自定义图表跨平台适配OpenHarmony
flutter·harmonyos·鸿蒙
奋斗的小青年!!1 小时前
Flutter + OpenHarmony:高性能搜索组件深度优化实战解析
flutter·harmonyos·鸿蒙
小雨下雨的雨2 小时前
Flutter 框架跨平台鸿蒙开发 —— ListView 控件之高效列表渲染艺术
flutter·华为·harmonyos