简体   繁体   English

当 TextField 或 TextFormField 获得焦点时,在 flutter 中将屏幕底部推到键盘顶部

[英]Push screen bottom on top of keyboard in flutter when TextField or TextFormField is focused

I want to achieve a layout where only the main button widget will always remain at the bottom of the scaffold.我想实现一个布局,其中只有主按钮小部件将始终保留在脚手架的底部。 Other widgets will be placed in a SingleChildScrollView -> Column .其他小部件将放置在SingleChildScrollView -> Column中。

But when the TextField or TextFormField is focused, the keyboard should push the full screen till the bottom of the layout, so that the button is visible.但是当TextFieldTextFormField获得焦点时,键盘应该将全屏推到布局的底部,以便按钮可见。

Using SingleChildScrollView only keeps the TextField or TextFormField above the keyboard, not the button too.使用 SingleChildScrollView 仅将TextFieldTextFormField保留在键盘上方,而不是按钮。

My code:我的代码:

body: SingleChildScrollView(
          physics: BouncingScrollPhysics(),
          child: Container(
            height: screenHeight(context) - kToolbarHeight - 24,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                PlaceHolder(),
                SizedBox(height: 20.0),
                Text('Select Time'),
                SizedBox(height: 10.0),
                PlaceHolder(),
                SizedBox(height: 20.0),
                PlaceHolder(),
                SizedBox(height: 20.0),
                // InputField is a TextFormField
                InputField(
                  controller: _dataController,
                  labelText: 'Enter Data',
                  fieldFocusNode: _dataFocusNode,
                  textInputType: TextInputType.text,
                ),
                SizedBox(height: 20.0),
                CheckboxListTile(),
                SizedBox(height: 20.0),
                PrimaryButton(
                  buttonText: 'Save',
                  onPressed: () {},
                ),
                SizedBox(height: 20.0),
              ],
            ),
          ),
        ),

Here's two screen layout.这是两个屏幕布局。 You can ignore all the other widgets except TextFormField and the Main Button .您可以忽略除TextFormFieldMain Button之外的所有其他小部件。

Screen One: Without keyboard ( TextField or TextFormField is not focused)屏幕一:没有键盘( TextFieldTextFormField不聚焦)

屏幕一:无键盘(TextField 或 TextFormField 未聚焦)

Screen Two: With keyboard ( TextField or TextFormField is focused)屏幕二:带键盘( TextFieldTextFormField聚焦)

屏幕二:带键盘(TextField 或 TextFormField 聚焦)

Follow this steps:请按照以下步骤操作:

1. Remove the Container with fixed height. 1.移除固定高度的Container

2. Add a Padding widget to the bottom of the page and set its bottom padding to MediaQuery.of(context).viewInsets.bottom . 2.在页面底部添加一个Padding小部件,并将其bottom填充设置为MediaQuery.of(context).viewInsets.bottom

3. Add reverse: true to the SingleChildScrollView . 3.添加reverse: trueSingleChildScrollView

4. Add resizeToAvoidBottomInset: false to the Scaffold . 4.resizeToAvoidBottomInset: false添加到Scaffold

5. Add resizeToAvoidBottomPadding: false to the Scaffold . 5.resizeToAvoidBottomPadding: false添加到Scaffold

Full code : (changes are marked with comments)完整代码:(更改用注释标记)

return Scaffold(
      resizeToAvoidBottomInset: false, // this is new
      resizeToAvoidBottomPadding: false, // this is new
      body: SingleChildScrollView( 
        reverse: true, // this is new 
        physics: BouncingScrollPhysics(),
        child: Column( // the container is removed
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            PlaceHolder(),
            SizedBox(height: 20.0),
            Text('Select Time'),
            SizedBox(height: 10.0),
            PlaceHolder(),
            SizedBox(height: 20.0),
            PlaceHolder(),
            SizedBox(height: 20.0),
            // InputField is a TextFormField
            InputField(
              controller: _dataController,
              labelText: 'Enter Data',
              fieldFocusNode: _dataFocusNode,
              textInputType: TextInputType.text,
            ),
            SizedBox(height: 20.0),
            CheckboxListTile(),
            SizedBox(height: 20.0),
            PrimaryButton(
              buttonText: 'Save',
              onPressed: null, // changed this since it had a syntax error
            ),
            Padding( // this is new
                padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom)
            ),
          ],
        ),
      ),
    );

Wrap your screen with SingleChildScrollViewSingleChildScrollView包裹你的屏幕

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM