Flutter:-键盘聚焦时导致键盘布局在底部溢出

时间:2020-05-09 06:44:09

标签: flutter dart flutter-layout

我有以下用于布局的代码。

@override
Widget build(BuildContext context) {
return Material(
  child: Scaffold(

//        resizeToAvoidBottomPadding: false,
//        resizeToAvoidBottomInset: false,
    appBar: PreferredSize(
      preferredSize: Size.fromHeight(70),
      child: AppBar(
        centerTitle: true,
        title: AutoSizeText(
          meal['name'],
          minFontSize: 30,
          maxFontSize: 50,
        ),
        backgroundColor: Colors.black,
        elevation: 1,
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () => null,
          ),
        ],
      ),
    ),
    body: Builder(
      builder: (context) {
        return Container(
          color: Colors.black,
          alignment: Alignment.center,
          child: FractionallySizedBox(
            widthFactor: 0.85,
            child: Container(
              child: Column(
                children: <Widget>[
                  Spacer(flex: 1,),
                  Container(
                    margin: EdgeInsets.only(bottom: 50),
                    child: Column(
                      children: <Widget>[
                        Container(
                          decoration: BottomWhiteDecoration(6.0),
                          padding: EdgeInsets.only(bottom: 8.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: <Widget>[
                              Text(
                                'Servings: 1',
                                style: TextStyle(color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                        Container(
                          child: Column(
                            children: <Widget>[
                              RowNutrimentalInfo('Calories', meal['calories'], showGram: false),
                              RowNutrimentalInfo('Protein', meal['macros']['proteins']),
                              RowNutrimentalInfo('Carbs', meal['macros']['carbs']),
                              RowNutrimentalInfo('Fat', meal['macros']['fats']),
                            ],
                          ),
                        )
                      ],
                    ),
                  ),
                Spacer(flex: 2,),
                  Container(
                    child: Column(
                      children: <Widget>[
                        Form(
                          key: this._mealFormKey,
                          child: Row(
                            children: <Widget>[
                              Expanded(
                                flex: 10,
                                child: TextFormField(...),
                              ),
                              Spacer(flex: 1,),
                              Expanded(
                                flex: 10,
                                child: TextFormField(...),
                              ),
                            ],
                          ),
                        ),
                        FractionallySizedBox(
                          widthFactor: .50,
                          child: OutlineButton(
                            borderSide: BorderSide(color: Colors.white),
                            color: Colors.black,
                            onPressed: _eatMeal,
                            child: Padding(
                              padding: EdgeInsets.all(20),
                              child: Text('Ok',
                                  style: TextStyle(color: Colors.white)),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  Spacer(flex: 2,),
                ],
              ),
            ),
          ),
        );
      },
    ),
  ),
);
}

但是,当我开始在文本字段之一中输入内容时,键盘会导致布局在底部溢出,如下图所示。

enter image description here

以下是我遇到的错误以及它在手机上的显示方式。有什么想法可以解决吗?我看到过类似的问题,例如将resizeToAvoidBottomPadding设置为false的解决方案:false,对我不起作用,因为键盘仍覆盖了文本输入。

The following assertion was thrown during layout:
A RenderFlex overflowed by 45 pixels on the bottom.

The relevant error-causing widget was: 
Column file:///C:/Users/bolon/StudioProjects/macro_counter/lib/Meal.dart:92:26
The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and 
black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the 
RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. 
If the content is legitimately bigger than the available space, consider clipping it with a ClipRect 
widget before putting it in the flex, or using a scrollable container rather than a Flex, like a 
ListView.

2 个答案:

答案 0 :(得分:2)

问题是您正在使用扩展窗口小部件,您会看到扩展窗口小部件本质上是灵活的,它们会根据可用空间消耗和缩小。如果不想,则需要指定高度。

因此,我已使用MediaQuery来根据设备分辨率设置widget,请检查以下解决方案,我已创建了代码演示。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutterlearningapp/colors.dart';

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _HomeScreen();
  }
}

class _HomeScreen extends State<HomeScreen> {
  @override
  void initState() {
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Material(
        child: Scaffold(
      appBar: AppBar(
        title: Text("Demo Scroll"),
      ),
      body: Container(
        height: double.infinity,
        width: double.infinity,
        color: Colors.black,
        child: SingleChildScrollView(

            child: Column(

              children: <Widget>[
                Container(
                  height: MediaQuery.of(context).size.height*0.6,
                  child: Column(
                    children: <Widget>[
                      CommonWidget("Calories", "150"),
                      CommonWidget("Protein", "9g"),
                      CommonWidget("Carbs", "15g"),
                      CommonWidget("Fat", "25g"),
                    ],
                  ),
                ),
                Container(
                  height: MediaQuery.of(context).size.height * 0.4,
                  child: Align(
                    alignment: Alignment.topCenter,
                    child: Column(
                      children: <Widget>[
                        Row(
                          children: <Widget>[
                            Expanded(
                              child: TextField(
                                style: new TextStyle(color: Colors.white),
                                decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.white),
                                    ),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.white),
                                    ),
                                    labelText: "Serving"),
                              ),
                            ),
                            SizedBox(
                              width: 10.0,
                            ),
                            Expanded(
                              child: TextField(
                                style: new TextStyle(color: Colors.white),
                                decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.white),
                                    ),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.white),
                                    ),
                                    labelText: "Germs"),
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 10.0,
                        ),
                        OutlineButton(
                          borderSide: BorderSide(color: Colors.white),
                          color: Colors.black,
                          onPressed: () {},
                          child: Padding(
                            padding: EdgeInsets.all(20),
                            child: Text('   Ok  ',
                                style: TextStyle(color: Colors.white)),
                          ),
                        )
                      ],
                    ),
                  ),
                )




              ],
            ),
          ),
        ),

    ));
  }

  Widget CommonWidget(var name, var value) {
    return Padding(
      padding: EdgeInsets.all(15.0),
      child: Column(
        children: <Widget>[
          Row(
            children: <Widget>[
              Expanded(
                child: Text(
                  name,
                  style: TextStyle(fontSize: 16.0, color: Colors.white),
                ),
              ),
              Expanded(
                child: Align(
                  alignment: Alignment.centerRight,
                  child: Text(value,
                      style: TextStyle(fontSize: 16.0, color: Colors.white)),
                ),
              )
            ],
          ),
          Divider(
            color: Colors.white,
            height: 20.0,
          )
        ],
      ),
    );
  }
}

输出将在示例

之后

enter image description here

答案 1 :(得分:0)

   Scaffold(
  resizeToAvoidBottomInset: true)

只需将其添加到您的代码中即可。