Flutter实现点击TextField时页面上移,与键盘保持24px间距
解决方案
要实现居中布局且键盘弹出时保持组件与键盘24px间距,你可以用SingleChildScrollView配合Center来替代原来的ListView或Column+Expanded方案,具体修正如下:
修正后的完整代码
import 'package:flutter/material.dart'; class RegistrationPage_ extends StatefulWidget { const RegistrationPage_({Key? key}) : super(key: key); @override State<RegistrationPage_> createState() => _RegistrationPage_State(); } class _RegistrationPage_State extends State<RegistrationPage_> { @override Widget build(BuildContext context) { // 标题文本 final qeydiyyatdanKec = const Text( '请注册', style: TextStyle( fontFamily: 'VisbyCF_Bold', fontWeight: FontWeight.w700, fontSize: 22, height: 1, color: Colors.black, ), ); // 信息文本 final infoTxt = const Text( '需要完成注册', style: TextStyle( fontFamily: 'VisbyCF_DemiBold', fontWeight: FontWeight.w600, fontSize: 14, height: 1.25, color: Color.fromRGBO(153, 153, 153, 1), ), ); // 手机号标题 final mobilNomreTxt = const Text( '手机号', style: TextStyle( fontFamily: 'VisbyCF_DemiBold', fontWeight: FontWeight.w600, fontSize: 12, height: 1.25, color: Color.fromRGBO(179, 179, 179, 1), ), ); // 手机号输入框 final mobilNomreInput = Container( decoration: BoxDecoration( border: Border.all(), color: const Color.fromRGBO(248, 248, 248, 1), ), height: 58, width: MediaQuery.of(context).size.width, child: const TextField( autofocus: true, keyboardType: TextInputType.number, style: TextStyle( fontFamily: 'VisbyCF_DemiBold', fontWeight: FontWeight.w600, fontSize: 14, height: 1.25, color: Colors.black, ), decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 20), border: InputBorder.none, hintText: '', hintStyle: TextStyle( fontFamily: 'VisbyCF_DemiBold', fontWeight: FontWeight.w600, fontSize: 14, height: 1.25, color: Color.fromRGBO(179, 179, 179, 1), ), ), ), ); // 底部按钮 final bottomButton = Container( decoration: BoxDecoration(border: Border.all()), child: TextButton( onPressed: () {}, child: const Text('继续'), ), ); return SingleChildScrollView( // 实时获取键盘高度,设置底部padding为键盘高度+24px,保证间距 padding: EdgeInsets.only( left: 24, right: 24, bottom: MediaQuery.of(context).viewInsets.bottom + 24, ), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ qeydiyyatdanKec, const SizedBox(height: 16), infoTxt, const SizedBox(height: 32), mobilNomreTxt, const SizedBox(height: 6), mobilNomreInput, const SizedBox(height: 32), bottomButton, const SizedBox(height: 88), ], ), ), ); } } void main() { runApp( const MaterialApp( home: Scaffold( body: RegistrationPage_(), ), ), ); }
关键修正点
- 用SingleChildScrollView替代ListView:避免手动计算屏幕高度的误差,同时支持键盘弹出时自动滚动内容
- MediaQuery.viewInsets.bottom:实时获取键盘的高度,给滚动视图底部额外添加24px间距,确保输入框与键盘的距离符合要求
- Center + Column居中布局:通过
mainAxisAlignment: MainAxisAlignment.center实现内容在屏幕居中,mainAxisSize: MainAxisSize.min让Column仅占用内容所需高度,避免不必要的布局重绘,解决Column+Expanded出现的先下移再上移的怪异现象 - 移除了原代码中手动计算屏幕高度和内容高度的逻辑,避免键盘弹出时屏幕尺寸变化导致的布局偏移
内容的提问来源于stack exchange,提问作者With Style
相关产品推荐
相关产品推荐

