Flutter中SlidingUpPanel内ListView滚动冲突问题求助
解决SlidingUpPanel嵌套ListView滚动冲突问题
要解决内部ListView滚动时外部SlidingUpPanel跟随滚动的问题,核心是阻止内部ListView的滚动事件向上冒泡到外层面板的ListView,可以通过以下两种方案实现:
方案一:使用NotificationListener拦截滚动事件
在内部ListView外层包裹NotificationListener<ScrollNotification>,捕获滚动事件后阻止其继续传递:
SlidingUpPanel( controller: _panelController, maxHeight: _panelHeightOpen, minHeight: _panelHeightClosed, parallaxEnabled: true, parallaxOffset: .5, borderRadius: const BorderRadius.only(topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0)), color: const Color(0xFFD6EDFF), body: Padding( padding: EdgeInsets.only(bottom: _paddingBottomMap), child: GoogleMap() ), panelBuilder: (controller) { return Builder(builder: (BuildContext context) { return ListView(padding: EdgeInsets.zero, controller: controller, children: <Widget>[ Container( margin: const EdgeInsets.symmetric(horizontal: 20), child: const Text("My Favorite") ), const SizedBox(height: 10), Container( height: _panelHeightOpen - 370, width: double.maxFinite, // 包裹NotificationListener拦截滚动事件 child: NotificationListener<ScrollNotification>( onNotification: (notification) { notification.stopPropagation(); return false; }, child: ListView.builder( controller: _listFavContronller, shrinkWrap: true, scrollDirection: Axis.vertical, itemCount: _favLocation.length, itemBuilder: (context, index) { return ListTile( onTap: () async { _panelController.close(); await goToCurrentLocation(); }, title: Text("${_favLocation[index].locationName}") ); } ), ), ) ] ); }); }, onPanelSlide: (position) async { setState(() {}); }, onPanelClosed: () { FocusScope.of(context).requestFocus(FocusNode()); }, )
方案二:调整内部ListView的滚动物理属性
给内部ListView设置专属滚动物理属性,让其优先处理滚动事件:
// 内部ListView.builder修改部分 ListView.builder( controller: _listFavContronller, shrinkWrap: true, scrollDirection: Axis.vertical, // 添加物理滚动属性,限制滚动事件范围 physics: const ClampingScrollPhysics(), itemCount: _favLocation.length, itemBuilder: (context, index) { return ListTile( onTap: () async { _panelController.close(); await goToCurrentLocation(); }, title: Text("${_favLocation[index].locationName}") ); } )
关键说明
- 方案一通过拦截滚动通知,彻底阻断事件向上传递,适配复杂场景更稳定;
- 方案二通过调整滚动物理属性,让内部ListView优先响应滚动,适合简单场景;
- 确保内部ListView使用独立的
_listFavContronller,不要与外层面板的controller复用。
内容的提问来源于stack exchange,提问作者Much Aris'z
相关产品推荐
相关产品推荐

