Flutter中滚动页面时Overlay和Focusnode遮挡Appbar问题如何解决?

问题场景:页面内共有12个TextFormField,全部放置在SingleChildScrollView组件中。滚动页面时,focusnode关联的overlay会显示在AppBar上方,导致AppBar被遮挡。
解决方案
这里提供两种常用的可行方案,可按需选择:
- 方案1:自动适配滚动位置,避免输入框靠近AppBar
给所有TextFormField添加scrollPadding属性,指定顶部避让AppBar的高度,输入框获焦时会自动滚动到避让后的可视区域,就不会出现overlay遮挡AppBar的问题。
修改后的示例代码如下:
import 'package:flutter/material.dart'; class Sample extends StatefulWidget { const Sample({super.key}); @override State<Sample> createState() => _SampleState(); } class _SampleState extends State<Sample> { var scaffoldkey=GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( appBar:AppBar(title: const Text('fvbnm'),backgroundColor: Colors.red,), body:SingleChildScrollView( child: Column( children: [ Table( children: [ TableRow( children: [ const Column(children: [Text('Name')],), Column( children: [ TextFormField( decoration: const InputDecoration(), // 顶部避让AppBar高度,可按需调整数值 scrollPadding: EdgeInsets.only(top: kToolbarHeight + 20, bottom: 20), ) ], ) ] ), TableRow( children: [ const Column(children: [Text('Name')],), Column( children: [ TextFormField( decoration: const InputDecoration(), scrollPadding: EdgeInsets.only(top: kToolbarHeight + 20, bottom: 20), ) ], ) ] ), // 剩余10个输入框同理添加scrollPadding属性 ], ) ], ), ), ); } }
- 方案2:滚动时自动失焦输入框
监听滚动事件,滚动触发时让当前获焦的输入框自动失去焦点,focus关联的overlay会自动消失,不会出现遮挡问题,适合不需要滚动时保持输入框激活的场景。
修改后的示例代码如下:
import 'package:flutter/material.dart'; class Sample extends StatefulWidget { const Sample({super.key}); @override State<Sample> createState() => _SampleState(); } class _SampleState extends State<Sample> { var scaffoldkey=GlobalKey<ScaffoldState>(); @override Widget build(BuildContext context) { return Scaffold( appBar:AppBar(title: const Text('fvbnm'),backgroundColor: Colors.red,), body: NotificationListener<ScrollUpdateNotification>( onNotification: (notification) { // 滚动时让当前获焦的输入框失焦 FocusManager.instance.primaryFocus?.unfocus(); return false; }, child: SingleChildScrollView( child: Column( children: [ Table( children: [ TableRow( children: [ const Column(children: [Text('Name')],), Column(children: [TextFormField(decoration:const InputDecoration())],) ] ), TableRow( children: [ const Column(children: [Text('Name')],), Column(children: [TextFormField(decoration:const InputDecoration())],) ] ), // 剩余输入框无需额外修改 ], ) ], ), ), ), ); } }
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

