Flutter Web中无法修改TextFormField的ScrollConfiguration问题
解决TextFormField嵌套ScrollBar出现双滚动条的问题
问题场景
想要让TextFormField始终显示滚动条,用ScrollBar组件包裹后,出现了两条滚动条(TextFormField自带的默认滚动条+外层手动添加的ScrollBar)。尝试用ScrollConfiguration禁用内部滚动条但未生效,现有代码如下:
Center( child: Container( height: 300, width: 400, decoration: BoxDecoration(border: Border.all(color: Colors.grey)), padding: const EdgeInsets.all(20), child: Scrollbar( controller: scrollController, thumbVisibility: true, child: Padding( padding: const EdgeInsets.only(right: 20.0), child: ScrollConfiguration( behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), child: TextFormField( maxLines: null, decoration: const InputDecoration(border: InputBorder.none), scrollController: scrollController, ), ), ), ), ), ))
双滚动条效果:
解决方案
TextFormField内部的滚动区域由EditableText实现,直接用ScrollConfiguration.of(context).copyWith(scrollbars: false)无法完全禁用它的默认滚动条。需要自定义ScrollBehavior,重写buildScrollbar方法返回null,彻底关闭内部滚动条:
步骤1:自定义ScrollBehavior
class NoScrollbarBehavior extends ScrollBehavior { @override Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) { // 返回null表示不渲染内部滚动条 return child; } }
步骤2:应用自定义行为到TextFormField
将原来的ScrollConfiguration替换为使用自定义的NoScrollbarBehavior,同时保持外层ScrollBar的配置不变:
Center( child: Container( height: 300, width: 400, decoration: BoxDecoration(border: Border.all(color: Colors.grey)), padding: const EdgeInsets.all(20), child: Scrollbar( controller: scrollController, thumbVisibility: true, child: ScrollConfiguration( behavior: NoScrollbarBehavior(), child: TextFormField( maxLines: null, decoration: const InputDecoration(border: InputBorder.none), scrollController: scrollController, ), ), ), ), )
关键说明
- 自定义
NoScrollbarBehavior通过重写buildScrollbar直接跳过内部滚动条的渲染,比copyWith(scrollbars: false)更彻底。 - 外层ScrollBar和TextFormField共享同一个
scrollController,确保滚动行为同步,且只显示外层的自定义滚动条。
内容的提问来源于stack exchange,提问作者manish kiranagi
相关产品推荐
相关产品推荐

