我试着做一个底部表,有一个文本字段,自动聚焦设置为true,这样键盘就会弹出。但是,键盘重叠在bottomsheet上。有没有办法移动键盘上方的底部?

Padding(
  padding:
      EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: Column(children: <Widget>[
    TextField(
      autofocus: true,
      decoration: InputDecoration(hintText: 'Title'),
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),
    TextField(
      decoration: InputDecoration(hintText: 'Additional details!'),
      keyboardType: TextInputType.multiline,
      maxLines: 4,
    ),]);

为了专注于键盘在BottomSheet - Wrap TextField在Padding Widget如下:

showModalBottomSheet(
              context: context,
              builder: (context) {
                return Container(
                  child: Padding(
                    padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
                    child: TextField(
                      autofocus: true,
                    ),
                  ),
                );
              }); 

要修复此问题

你所需要的就是使用MediaQuery.of(context).viewInsets.bottom填充键盘 为了更保险,设置底部表格对话框的isScrollControlled = true,这将允许底部表格获得所需的全部高度。

请注意

如果您的BottomSheetModel是Column,请确保添加mainAxisSize: mainAxisSize。Min,否则床单会覆盖整个屏幕。 工作与多个TextField或TextFormField

例子

showModalBottomSheet(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),
        backgroundColor: Colors.black,
        context: context,
        isScrollControlled: true,
        builder: (context) => Padding(
          padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
          child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12.0),
                    child: Text('Enter your address',
                        style: TextStyles.textBody2),
                  ),
                  SizedBox(
                    height: 8.0,
                  ),
                  TextField(
                      decoration: InputDecoration(
                        hintText: 'adddrss'
                      ),
                      autofocus: true,
                      controller: _newMediaLinkAddressController,
                    ),
                  

                  SizedBox(height: 10),
                ],
              ),
        ));

请注意:

shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),

这不是必须的。只是我要创建一个圆形的底页。

更新

Flutter 2.2又打破了改动!”现在你需要再次给底部填充,这样键盘就不会重叠在底部。


用脚手架小部件包装表单,然后用SingleChildScrollView包装TextFormField:


 return Container(
          height: screenHeight * .66,
          child: Scaffold(
             body: Form(
               key: _form,
               child: SingleChildScrollView(
                 child:TextFormField()
               )
              )
             )
           )

添加:

isScrollControlled: true表示showModalBottomSheet 填充:MediaQuery.of(上下文)。viewInsets为生成器中的小部件 列/换行都可以

showModalBottomSheet<void>(
  isScrollControlled: true,
  context: context,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.only(
        topLeft: Radius.circular(30.0),
        topRight: Radius.circular(30.0)),
  ),
  builder: (BuildContext context) {
    return Padding(
        padding: MediaQuery.of(context).viewInsets,
        child: Container(
            child: Wrap(
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            ),
            TextField(
              decoration: InputDecoration(
                  border: InputBorder.none,
                  hintText: 'Enter a search term'),
            )
          ],
        )));
  },
);

更新2020年2月25日更好的解决方案

showModalBottomSheet(
 isScrollControlled: true,
 builder: (BuildContext context) {

    return SingleChildScrollView(
      child: Container(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0.0), // content padding
          child: Form(...)) // From with TextField inside


});

在结合不同的解决方案后,我得到了这个:

如果你不想全屏,也不想使用填充

  showModalBottomSheet(
      context: context,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      enableDrag: true,
      isDismissible: true,
      useRootNavigator: true,
      builder: (BuildContext ctx) {
        return Scaffold( // use CupertinoPageScaffold for iOS
          backgroundColor: Colors.transparent,
          resizeToAvoidBottomInset: true, // important
          body: SingleChildScrollView(
            child: Form(
              child: Container(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: <Widget>[
                    TextFormField(),
                    TextFormField(),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );

在Flutter(通道母版,v1.15.3-pre。37,适用于Mac OS X 10.15.2 19C57, locale en-US)


试试这个

我的解决方案是

使用isScrollControlled: true 添加填充 填充:EdgeInsets。只有(底:MediaQuery.of(上下文).viewInsets.bottom) 在SingleChildScrollView中包装布局

示例代码

Future<void> future = showModalBottomSheet(
  context: context,
  isDismissible: true,
  isScrollControlled: true,
  backgroundColor: Colors.white.withOpacity(0.2),
  builder: (context) => SingleChildScrollView(
    child: GestureDetector(
      child: Padding(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom
        ),
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          child: Column(
            children: <Widget>[
              // add your widget here
            ],
          ),
        ),
      )
    ),
  )
);

我通过增加打开键盘时子部件的高度来解决这个问题。 MediaQuery.of(context). viewinsets的初始值。底部为0,当键盘聚焦时它会改变。

showModalBottomSheet<void>(
      enableDrag: true,
      isScrollControlled: true,
      context: context,
      builder: (BuildContext context) {
        return Card(
          color: Colors.white,
          child: Container(
            height: MediaQuery.of(context).size.height / 2 +
                MediaQuery.of(context).viewInsets.bottom,
            child: Column(
              children: <Widget>[
                TextField(),
                TextField(),
              ],
            ),
          ),
        );
      },
    );

如果你有全屏或固定大小的showModalBottomSheet,不要使用填充,这不会解决你的问题。使用边距代替填充,就像这样:

  showModalBottomSheet(
          context: context,
          builder: (context) {
            return Container(
                marign: EdgeInsets.only(
                    bottom: MediaQuery.of(context).viewInsets.bottom),
                child: TextField()
            );
          }); 

showModalBottomSheet(
 isScrollControlled: true,
 builder: (BuildContext context) {

    return SingleChildScrollView(
      child: Container(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: Padding(
          padding: const EdgeInsets.all(15.0), // content padding
          child: Container())});

注意:这一行完成了所有的魔术


不要在构建器中使用builder:(BuildContext context){},而是使用builder: (context) {}

有了这个解决方案,我的模态底部表坚持状态栏(行为像脚手架与resizeToAvoidBottomInset: false),并允许查看所有的表单字段和滚动的形式,如果它仍然需要查看底部文本字段。

要了解更多细节,这里是我找到解决方案的链接- https://github.com/flutter/flutter/issues/18564#issuecomment-602604778


在github上找到这个

Padding(
  padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
  child: TextField()
)

给那些不能解决问题的人尝试所有的答案。这些答案是正确的,但不太清楚。

当使用

MediaQuery.of(上下文).viewInsets.bottom)

make sure your context variable is using the one provided by bottom sheet builder property.

c builder:(* * * *) = > MediaQuery.of (c * * * *)


更新2021年5月扑动2.2! 现在你需要给底部填充。下面写的是一个错误。

更新2020 !

这个答案是正确的,但是你现在不需要给底部填充! 找到并删除这一行:

填充:MediaQuery.of .viewInsets(上下文)


试试这个。

showModalBottomSheet(
        isScrollControlled: true,
        context: context,
        builder: (context) {
          return AnimatedPadding(
              padding: MediaQuery.of(context).viewInsets,
              duration: const Duration(milliseconds: 100),
              curve: Curves.decelerate,
              child: Container(
                  child: Wrap(
                children: [
                  TextField(
                    decoration: InputDecoration(labelText: "1"),
                  ),
                  TextField(
                    decoration: InputDecoration(labelText: "2"),
                  ),
                  TextField(
                    decoration: InputDecoration(labelText: "3"),
                  ),
                ],
              )));
        },
      )

你应该用这个,

showModalBottomSheet(
    isScrollControlled: true,
    context: context,
    shape: RoundedRectangleBorder(
      // <-- for border radius
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(10.0),
        topRight: Radius.circular(10.0),
      ),
    ),
    builder: (BuildContext context) {
      return SingleChildScrollView(
        padding:
            EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
        child: drunkenWidget()...

//BTW, Never ever Drink

简单的解决方案,你可以自定义这个:

Container(
          margin: EdgeInsets.only(left: 15),
          child: InkWell(
              onTap: () {
                showModalBottomSheet(
                    isScrollControlled : true,
                    context: context,
                    backgroundColor: Colors.transparent,
                    builder: (context) {
                      return Container(
                        padding: EdgeInsets.only(top: 15, left: 15, right: 15, bottom: 10),
                        width: double.infinity,
                        decoration: BoxDecoration(
                          color: AppTheme.leadItemColor1,
                          borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
                        ),
                        child: Column(
                          children: [
                            _assignTo(widget.viewModel, context),
                            SizedBox(height: 12,),
                            txtComment(widget.viewModel),
                            SizedBox(height: 12,),
                            CRMButton(
                              title: 'Select',
                              onTap: () async {
                                Navigator.pop(context);
                                await widget.viewModel.updateStatus(7, why: "${ConstantData.lostOptions[_selectedNumber]}");
                              },
                            )
                          ],
                        ),
                      );
                    },
                );
              },
              child: CustomTabBarItem1(
                image: widget.viewModel.leadDetail.success.lStatus == 7 ? 'assets/appimages/LeadDetail/icons-03-01.png' : 'assets/appimages/LeadDetail/icons-04-01.png',
                bottomTitle: 'Lost',
                topTitle: widget.viewModel.leadDetail.success.lStatus > 7 ? 'assets/appimages/LeadDetail/Ellipse 61@2x.png' : widget.viewModel.leadDetail.success.lStatus == 7 ? 'assets/appimages/LeadDetail/Group 486-1.png' : 'assets/appimages/LeadDetail/Ellipse-61@3x.png',
                height : widget.viewModel.leadDetail.success.lStatus == 7 ? "0" : "1",
              )),
        ),

只需添加

if (_isEditing) SizedBox(height: MediaQuery.of(context).viewInsets.bottom),

在键盘和隐藏所有其他内容下面的文本框与

if (!_isEditing) Widget(...),

包:https://pub.dev/packages/modal_bottom_sheet

将小部件包装到Padding中,并像这样设置Padding ==>

padding: MediaQuery.of(context).viewInsets // viewInsets will decorate your screen

你可以使用 showMaterialModalBottomSheet或showModalBottomSheet或showCupertinoModalBottomSheet

showModalBottomSheet(
        context: context,
        barrierColor: popupBackground,
        isScrollControlled: true, // only work on showModalBottomSheet function
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(borderRadiusMedium),
                topRight: Radius.circular(borderRadiusMedium))),
        builder: (context) =>  Padding(
            padding: MediaQuery.of(context).viewInsets,
            child: Container(
                   height: 400, //height or you can use Get.width-100 to set height
                   child: <Your Widget here>
             ),)),)


把它添加到你的底页的最后一个小部件之后

Padding(padding: EdgeInsets.only(bottom:MediaQuery.of(context).viewInsets.bottom))

如果你还没有找到你的问题。我认为你们在BuilderContext中漏掉了。有时候当你实现modalBottomSheet时,它只会给你context参数。用BuildContext添加context。

 builder: (BuildContext context) {  //-Here is your issue add BuilderContext class name as it as 
          return Padding(
            padding: MediaQuery.of(context).viewInsets,
            child: SingleChildScrollView(
              child: Padding(
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
                child: new Container(

showModalBottomSheet(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(15.0),
      ),
      context: context,
      isScrollControlled: true,
      builder: (builder) {
        return Container(
          height: MediaQuery.of(context).size.height - 40,
          padding: MediaQuery.of(context).viewInsets,
          child: <Your Widget Here>,
        );
      },
    );


import 'dart:async'; import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; import '../weight/boostrap/flutter_bootstrap.dart'; import '../weight/boostrap/bootstrap_widgets.dart'; /* TextEditingController txtname = TextEditingController(); showModalBottomSheet( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), builder: (context) => SingleChildScrollView( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), child: new AddItem( tektk: 'Category', tektd: 'Add', txtname: txtname, ismultik:false, onPressed: () {}), ), ); */ class AddItem extends StatelessWidget { const AddItem( {Key? key, required this.ismultik, required this.tektd, required this.tektk, required this.txtname, required this.onPressed}) : super(key: key); final bool ismultik; final String tektk; final String tektd; final VoidCallback? onPressed; final TextEditingController txtname; @override Widget build(BuildContext context) { final MediaQueryData mediaQueryData = MediaQuery.of(context); bootstrapGridParameters(gutterSize: 10); return Padding( padding: mediaQueryData.viewInsets, child: Container( padding: EdgeInsets.only(bottom: 90.0, left: 10.0, right: 10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ListTile( trailing: SizedBox.fromSize( size: Size(35, 35), child: ClipOval( child: Material( color: Colors.indigo, child: InkWell( splashColor: Colors.white, onTap: () { Navigator.pop(context); }, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.close, color: Colors.white), ], ), ), ), ), ), ), BootstrapRow(height: 0, children: [ BootstrapCol( sizes: 'col-md-12', child: TextField( style: TextStyle(color: Colors.black), decoration: new InputDecoration( border: new OutlineInputBorder( borderSide: new BorderSide(color: Colors.white)), labelText: tektk, ), keyboardType: ismultik == true ? TextInputType.multiline : TextInputType.text, maxLines: null, minLines: 1, controller: txtname, ), ), BootstrapCol( sizes: 'col-md-12', child: ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.green, // background onPrimary: Colors.white, // foreground ), onPressed: onPressed, child: Text(tektd)), ), ]), ], ), ), ); } }


将此添加到路由器链接模态底部表中

 showModalBottomSheet(              
     context: context,
     isScrollControlled: true,
      builder: (BuildContext context) {
      return Messagescr();
      }
    );

在你的脚手架上也去掉这条线:

resizeToAvoidBottomInset : false,