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
相关产品推荐
相关产品推荐

