Flutter登录页键盘弹出报RenderFlex溢出,套滚动组件后UI消失求解决
问题原因
- 你的布局外层
Column中使用了Spacer()组件,它的作用是填充Column主轴方向的剩余可用空间。当你直接给外层Column套SingleChildScrollView/ListView时,可滚动组件的主轴高度是无边界的,Spacer()无法计算需要填充的空间大小,最终导致布局异常、UI完全消失。 - 软键盘弹出时触发overflow是因为原布局
Column高度固定为屏幕可视高度,软键盘弹出后会挤占页面可用高度,内容高度超出剩余可用高度就会触发溢出报错。
解决方案
修改逻辑如下:
- 外层包裹
SingleChildScrollView实现滚动能力 - 用
LayoutBuilder获取当前可视区域的高度,给内部Column指定明确的高度,保证Spacer()可以正常计算填充空间 - 保留原有的所有布局元素和样式,不需要修改业务逻辑代码
修改后完整代码:
import 'package:flutter/material.dart'; import 'package:flutter_chat_application_1/modals/customtheme.dart'; import 'package:flutter_chat_application_1/widgets/customappbar.dart'; import 'package:flutter_chat_application_1/widgets/widget.dart'; class SignIn extends StatefulWidget { const SignIn({Key? key}) : super(key: key); @override _SignInState createState() => _SignInState(); } class _SignInState extends State<SignIn> { @override Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar(), // 保留默认的resizeToAvoidBottomInset=true,自动适配软键盘 body: SingleChildScrollView( // 保证内容不足一屏的时候也可以滚动,软键盘弹出时不会卡顿 physics: const AlwaysScrollableScrollPhysics(), child: Container( padding: const EdgeInsets.symmetric(horizontal: 24), // 用LayoutBuilder获取可视区域高度 child: LayoutBuilder( builder: (context, constraints) { return SizedBox( // 高度取当前可视区域的高度,保证Spacer可以正常工作 height: constraints.maxHeight, child: Column( mainAxisSize: MainAxisSize.max, children: [ const Spacer(), Form( child: Column( children: [ TextFormField( style: myTextStyle(), decoration: textFieldInputDecoration('email')), TextFormField( style: myTextStyle(), decoration: textFieldInputDecoration('password'), ) ], ), ), const SizedBox( height: 16, ), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: TextButton( onPressed: () {}, child: Text( 'Forgot Password?', style: myTextStyle(), ), )) ], ), const SizedBox( height: 16, ), GestureDetector( onTap: () {}, child: Container( padding: const EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(30), gradient: const LinearGradient( colors: [Color(0xff007EF4), Color(0xff2A75BC)])), width: MediaQuery.of(context).size.width, child: Text( 'Sign In', style: biggerTextStyle(), textAlign: TextAlign.center, ), ), ), const SizedBox( height: 16, ), GestureDetector( onTap: () {}, child: Container( padding: const EdgeInsets.symmetric(vertical: 16), width: MediaQuery.of(context).size.width, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30)), child: Text( 'Sign in with Google', style: TextStyle(fontSize: 17, color: CustomTheme.textColor), textAlign: TextAlign.center, ), ), ), const SizedBox( height: 16, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Don\'t have account?', style: myTextStyle(), ), TextButton( onPressed: () {}, child: const Text('Register Now', style: TextStyle( decoration: TextDecoration.underline, color: Colors.white, fontSize: 16, ))) ], ), const SizedBox( height: 10, ) ], ), ); } ), ), )); } }
修改后软键盘弹出时页面会自动滚动,不会出现组件重叠和overflow报错,原有的布局居中效果也会完全保留。
内容的提问来源于stack exchange,提问作者HITESH NATH
相关产品推荐
相关产品推荐

