Flutter:解决Bottom Sheet中输入框被键盘遮挡的问题
解决Bottom Sheet中评论输入框被键盘遮挡的问题
核心问题分析
showModalBottomSheet默认未开启键盘适配,需启用滚动控制让Bottom Sheet响应键盘高度变化viewInsets内边距添加层级错误,应作用在Bottom Sheet根容器,而非输入框父级组件- 固定Bottom Sheet高度导致无法自适应键盘弹出后的布局调整
修改步骤及代码
1. 调整showModalBottomSheet配置
添加isScrollControlled: true开启键盘适配:
showModalBottomSheet( useRootNavigator: true, isScrollControlled: true, // 关键:开启滚动控制,让Bottom Sheet适配键盘高度 shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(16), ), ), context: context, builder: (BuildContext context) { return CustomBottomSheetBuilder( tinggi: MediaQuery.of(context).size.height, isi: const [ CommentContent(), ], header: true, judul: 'Comments', ); });
2. 修改CustomBottomSheetBuilder布局
去掉固定高度,将viewInsets padding移到根容器,让Bottom Sheet自适应高度:
Container( constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height - kBottomNavigationBarHeight, ), decoration: BoxDecoration( color: MyColor.white, borderRadius: const BorderRadius.only( topLeft: Radius.circular(25.0), topRight: Radius.circular(25.0), ), ), child: Padding( padding: MediaQuery.of(context).viewInsets, // 根容器添加viewInsets,避开键盘 child: Column( mainAxisSize: MainAxisSize.min, // 让Column仅占用所需高度 children: [ widget.header == true ? Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( width: .5, color: MyColor.neutralLow, ), ), ), height: 64, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.judul == null ? '' : widget.judul!, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: MyColor.neutralHigh, ), ), TextActionButton( teks: 'Cancel', onPressed: () { Navigator.pop(context); }, ), ], ), ), ) : const SizedBox(height: 48), Expanded( child: Padding( padding: const EdgeInsets.all(16), child: ListView( children: widget.isi, ), ), ), ], ), ), );
3. 优化CommentContent布局
去掉输入框外层的Flexible和多余的viewInsets padding,简化布局:
ConstrainedBox( constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.8, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Flexible( child: ListView.builder( shrinkWrap: true, reverse: true, itemBuilder: ((context, index) { final Comment comments = commentList[index]; return Card( shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(3)), ), child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ CircleAvatar( radius: 12, child: Image.asset(comments.image), ), Padding( padding: const EdgeInsets.only(left: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( comments.name, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, ), ), Text( comments.day, style: TextStyle( fontSize: 10, color: MyColor.neutralMediumLow, ), ), ], ), ), const Spacer(), CustomPopupMenuButton( itemBuilder: (context) => [ PopupMenuItem( value: 1, child: Row( children: [ Text( "Delete Comment", style: TextStyle(color: MyColor.danger), ), ], ), ), ], onSelected: (value) { if (value == 1) {} }, ), ], ), const SizedBox(height: 10), Padding( padding: const EdgeInsets.only(right: 8), child: Text(comments.comment), ) ], ), ), ); }), itemCount: commentList.length, ), ), Padding( padding: const EdgeInsets.only(top: 8), child: TextBox( textEditingController: commentController, hintText: 'Type what are you thinking here ...', suffixIcon: IconButton( onPressed: () {}, icon: const Icon(Icons.send), ), ), ), ], ), );
修改说明
isScrollControlled: true:让Bottom Sheet可根据键盘高度动态调整自身高度,是解决键盘遮挡的核心开关- 根容器添加
viewInsetspadding:确保整个Bottom Sheet向上偏移避开键盘,而非仅调整输入框位置 - 移除固定高度:避免布局被固定死,允许Bottom Sheet在键盘弹出时自适应缩小高度
- 简化输入框布局:去掉不必要的
Flexible,让输入框保持合适高度,避免布局冲突
内容的提问来源于stack exchange,提问作者Ardhya Chandra
相关产品推荐
相关产品推荐

