You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SlidingUpPanel内嵌横向ListView滑动时面板联动问题求解

解决SlidingUpPanel与嵌套水平ListView的滚动冲突问题

当垂直ListView内容不足时,滑动水平ListView会带动SlidingUpPanel移动,核心原因是手势识别冲突——水平滑动时,垂直方向的手势被SlidingUpPanel的拖动逻辑捕获了。可以通过监听水平ListView的滚动状态,动态控制SlidingUpPanel的可拖动性来解决。

具体实现步骤:

  • 为水平ListView添加专属的ScrollController,监听其滚动状态
  • 在SlidingUpPanel中通过isDraggable属性,根据水平滚动状态切换面板的可拖动性
  • 正确管理控制器生命周期,避免内存泄漏

修改后的完整代码:

import 'package:flutter/material.dart';
import 'package:sliding_up_panel/sliding_up_panel.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late ScrollController _horizontalScrollController;
  bool _isHorizontalScrolling = false;
  final PanelController _panelController = PanelController();

  @override
  void initState() {
    super.initState();
    _horizontalScrollController = ScrollController();
    // 监听水平滚动状态
    _horizontalScrollController.position.isScrollingNotifier.addListener(_updateScrollState);
  }

  @override
  void dispose() {
    _horizontalScrollController.position.isScrollingNotifier.removeListener(_updateScrollState);
    _horizontalScrollController.dispose();
    _panelController.dispose();
    super.dispose();
  }

  void _updateScrollState() {
    setState(() {
      _isHorizontalScrolling = _horizontalScrollController.position.isScrollingNotifier.value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Flutter 示例"),
        ),
        body: SlidingUpPanel(
          borderRadius: BorderRadius.circular(20),
          minHeight: 80,
          maxHeight: MediaQuery.sizeOf(context).height * 0.8,
          panelController: _panelController,
          // 水平滚动时禁止面板拖动
          isDraggable: !_isHorizontalScrolling,
          panelBuilder: (ScrollController sc) => _panel(sc, _horizontalScrollController),
          body: const Center(
            child: Text("这是滑动面板下方的内容"),
          ),
        ),
      ),
    );
  }
}

Widget _panel(ScrollController verticalSc, ScrollController horizontalSc) {
  return ListView(
    controller: verticalSc,
    children: List.generate(3, (index) {
          return const Padding(
              padding: EdgeInsets.all(10),
              child: FlutterLogo(
                size: 100,
              ));
        })
      ..add(SizedBox(
          height: 100,
          child: ListView(
            controller: horizontalSc,
            scrollDirection: Axis.horizontal,
            children: List.filled(
                6, const Padding(padding: EdgeInsets.all(10), child: FlutterLogo(size: 100))),
          ))),
  );
}

原理说明:

  • 通过_horizontalScrollController监听水平ListView的滚动状态,当isScrollingNotifier.value为true时,标记正在进行水平滚动
  • 将SlidingUpPanel的isDraggable设置为!_isHorizontalScrolling,即水平滚动时禁止面板拖动,彻底避免手势冲突
  • 使用PanelController辅助管理面板生命周期,确保资源正确释放

内容的提问来源于stack exchange,提问作者Yant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:56:03