【问题标题】:Bottom content of the screen are not visible in some phones屏幕底部的内容在某些手机中不可见
【发布时间】:2020-12-23 15:54:47
【问题描述】:

我正在开发一个 Flutter 应用,下面是我的 UI 代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'package:flutter/widgets.dart';

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: ConstrainedBox(
          constraints:  BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
          child: Container(child: _LoginUI(),),)
      ),
    );
  }
}

class _LoginUI extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LoginState();
  }
}



class _LoginState extends State<_LoginUI> {

  final _formKey = GlobalKey<FormState>();
  //FIXME When validate error occures, the fields get super small

  

  TextEditingController _phoneNumber = TextEditingController();
  TextEditingController _passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {


    return Container(
        height: double.infinity,
        width: double.infinity,
        child:
         Stack(
          fit: StackFit.loose,
          children: <Widget>[
            SafeArea(
              child: Container(
                margin: EdgeInsets.only(top: 25),
                child: Image.asset("assets/images/login_image.png"),
              ),
            ),
            
            Positioned(
              top: 275,
              child: Container(
                height: 600,
                width: MediaQuery.of(context).size.width,
                decoration: new BoxDecoration(
                    color: Colors.white,
                    borderRadius: new BorderRadius.only(
                        topLeft: const Radius.circular(40.0),
                        topRight: const Radius.circular(40.0))),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Flexible(
                          child: Container(
                            margin:
                                EdgeInsets.only(top: 20, left: 10, right: 10),
                            child: Image.asset(
                                "assets/images/logo.png",
                                width: 200,
                                height: 50),
                          ),
                        )
                      ],
                    ),
                    Form(
                      key: _formKey,
                      child: Column(
                        children: <Widget>[
                          Container(
                              margin: EdgeInsets.only(
                                top: 40,
                              ),
                              child: SizedBox(
                                width: MediaQuery.of(context).size.width * .90,
                                height: 36,
                                child: TextFormField(
                                  controller: _phoneNumber,
                                  validator: (value) {
                                    if (value.isEmpty) {
                                      return 'Please enter some text';
                                    }
                                    return null;
                                  },
                                  decoration: InputDecoration(
                                    filled: true,
                                    fillColor: Colors.white,
                                    contentPadding: const EdgeInsets.only(
                                        top: 2, bottom: 2, left: 8),
                                    border: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(30.0),
                                    ),
                                    hintText: "Email",
                                  ),
                                ),
                              )),
                          Container(
                            margin: EdgeInsets.only(
                              top: 15,
                            ),
                            child: SizedBox(
                              height: 36,
                              width: MediaQuery.of(context).size.width * .90,
                              child: TextFormField(
                                controller: _passwordController,
                                keyboardType: TextInputType.visiblePassword,
                                validator: (value) {
                                  if (value.isEmpty) {
                                    return 'Please enter some text';
                                  }
                                  return null;
                                },
                                decoration: InputDecoration(
                                  filled: true,
                                  fillColor: Colors.white,
                                  contentPadding: const EdgeInsets.only(
                                      top: 2, bottom: 2, left: 8),
                                  border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(30.0),
                                  ),
                                  hintText: "Password",
                                ),
                              ),
                            ),
                          ),
                          Align(
                            alignment: Alignment.bottomRight,
                            child: Container(
                                margin: EdgeInsets.only(
                                    top: 1, left: 10, right: 10),
                                child: FlatButton(
                                  onPressed: () {
                                    Navigator.pushNamed(context, "/password-reset");
                                  },
                                  child: Text("Forgot Password?",
                                      style: TextStyle(
                                          fontFamily: 'Roboto-Medium',
                                          fontSize: 14.0,
                                          letterSpacing: 1.25,
                                          color:
                                              Color.fromRGBO(75, 56, 137, 80))),
                                )),
                          ),
                          Container(
                              margin:
                                  EdgeInsets.only(top: 1, left: 10, right: 10),
                              child: SizedBox(
                                width: MediaQuery.of(context).size.width * .90,
                                child: RaisedButton(
                                  color: Color.fromRGBO(75, 56, 137, 80),
                                  textColor: Colors.white,
                                  shape: RoundedRectangleBorder(
                                      borderRadius:
                                          new BorderRadius.circular(18.0),
                                      side: BorderSide(
                                          color:
                                              Color.fromRGBO(75, 56, 137, 80))),
                                  child: Text(
                                    "LOGIN",
                                    style: Theme.of(context).textTheme.button,
                                  ),
                                  onPressed: () {

                                    String email = _phoneNumber.text;
                                    String password = _passwordController.text;
                                    
                                    if (_formKey.currentState.validate()) {
                                      loginProcess(email, password);
                                    }
                                  },
                                ),
                              ))
                        ],
                      ),
                    ),
                    Container(
                        margin: EdgeInsets.only(top: 1, left: 10, right: 10),
                        child: FlatButton(
                          onPressed: () {
                            Navigator.pushNamed(context, "/register");
                          },
                          child: RichText(
                            text: TextSpan(children: <TextSpan>[
                              TextSpan(
                                text: "Not a member yet? ",
                                style: TextStyle(fontFamily: 'Roboto-Regular',  fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 )),
                              ),
                              TextSpan(
                                text: "Create an Account",
                                style: TextStyle(decoration: TextDecoration.underline,  fontFamily: 'Roboto-Regular',  fontSize: 14.0, letterSpacing: 0.25, color:Color.fromRGBO(75, 56, 137, 80 ),
                              ),)
                            ]),
                          ),
                        )),
                  ],
                ),
              ),
            ),
          ],
        )
        //child: Image.asset("assets/images/login_image.png"),
        );
  }

  

bELOW 图片显示了我在大多数手机中获得的 UI 是正确的,而我在某些手机中获得的 UI 是不准确的。

如您所见,在不准确的版本中,底部的按钮缺失。这特别发生在Sony Xperia 系列中,它的屏幕尺寸为 4.6 英寸,分辨率为 720x1280。

解决此问题的最简单方法是将positioned 中的值更改为 250,这会使图像下方的整个块更加向上。但这在某些手机中很难看,因为它覆盖了顶部图像。我有另一个与此问题相同的屏幕,它有更多字段。因此,将 positioned 值设置为其他值这样的解决方案将不起作用。

确保整个屏幕在所有手机中可见的最佳解决方案是什么?

【问题讨论】:

    标签: android ios flutter flutter-layout


    【解决方案1】:

    我的方法如下:

    然后用SafeArea 包裹Scaffold,(这是可选的)

    如果 Widget 在当前设备中正确定位,例如当前模拟器, 其分辨率为480x800。小部件位于250px(您的用例中的一个示例)

    然后它位于距顶部约 31.25% ((250/800)*100) 处。

    然后我会使用MediaQuery.of(Context).size.height*0.3125 来定位顶部的小部件。

    现在无论手机的高度如何,小部件都将始终放置在距顶部 31.25% 处。

    同样,你也可以为left的位置做/


    我的建议也是对小部件的宽度和高度执行相同操作,以便小部件的大小也与设备屏幕相同。对于某些设备来说,看起来不会太大或太小。不是针对每个小部件,而是针对某些小部件。

    【讨论】:

      【解决方案2】:

      我更改了您的代码,但我没有资产文件,因此我更改了 SizedBox。

      import 'package:flutter/cupertino.dart';
      import 'package:flutter/material.dart';
      
      import 'package:flutter/widgets.dart';
      
      class LoginPage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            backgroundColor: Colors.white,
            body: _LoginUI(),
          );
        }
      }
      
      class _LoginUI extends StatefulWidget {
        @override
        State<StatefulWidget> createState() {
          return _LoginState();
        }
      }
      
      class _LoginState extends State<_LoginUI> {
        final _formKey = GlobalKey<FormState>();
        //FIXME When validate error occures, the fields get super small
      
        TextEditingController _phoneNumber = TextEditingController();
        TextEditingController _passwordController = TextEditingController();
      
        @override
        Widget build(BuildContext context) {
          return Container(
            child: SafeArea(
              child: LayoutBuilder(builder:
                  (BuildContext context, BoxConstraints viewportConstraints) {
                return SingleChildScrollView(
                  reverse: true,
                  child: ConstrainedBox(
                    constraints: BoxConstraints(
                      minHeight: viewportConstraints.maxHeight,
                    ),
                    child: Column(
                      children: <Widget>[
                        Container(
                          margin: EdgeInsets.only(top: 25),
                          // child: Image.asset("assets/images/login_image.png"),
                          child: SizedBox(
                            height: 200,
                            child: Text('Login_image'),
                          ),
                        ),
                        Container(
                          width: MediaQuery.of(context).size.width,
                          decoration: new BoxDecoration(
                              color: Colors.white,
                              borderRadius: new BorderRadius.only(
                                  topLeft: const Radius.circular(40.0),
                                  topRight: const Radius.circular(40.0))),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: <Widget>[
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Flexible(
                                    child: Container(
                                      margin: EdgeInsets.only(
                                          top: 20, left: 10, right: 10),
                                      child: Container(
                                        height: 50,
                                        child: Text('LOGO'),
                                      ),
                                      //Image.asset("assets/images/logo.png",
                                      //    width: 200, height: 50),
                                    ),
                                  )
                                ],
                              ),
                              Form(
                                key: _formKey,
                                child: Column(
                                  children: <Widget>[
                                    Container(
                                        margin: EdgeInsets.only(
                                          top: 40,
                                        ),
                                        child: SizedBox(
                                          width:
                                              MediaQuery.of(context).size.width * .90,
                                          height: 36,
                                          child: TextFormField(
                                            controller: _phoneNumber,
                                            validator: (value) {
                                              if (value.isEmpty) {
                                                return 'Please enter some text';
                                              }
                                              return null;
                                            },
                                            decoration: InputDecoration(
                                              filled: true,
                                              fillColor: Colors.white,
                                              contentPadding: const EdgeInsets.only(
                                                  top: 2, bottom: 2, left: 8),
                                              border: OutlineInputBorder(
                                                borderRadius:
                                                    BorderRadius.circular(30.0),
                                              ),
                                              hintText: "Email",
                                            ),
                                          ),
                                        )),
                                    Container(
                                      margin: EdgeInsets.only(
                                        top: 15,
                                      ),
                                      child: SizedBox(
                                        height: 36,
                                        width:
                                            MediaQuery.of(context).size.width * .90,
                                        child: TextFormField(
                                          controller: _passwordController,
                                          keyboardType: TextInputType.visiblePassword,
                                          validator: (value) {
                                            if (value.isEmpty) {
                                              return 'Please enter some text';
                                            }
                                            return null;
                                          },
                                          decoration: InputDecoration(
                                            filled: true,
                                            fillColor: Colors.white,
                                            contentPadding: const EdgeInsets.only(
                                                top: 2, bottom: 2, left: 8),
                                            border: OutlineInputBorder(
                                              borderRadius:
                                                  BorderRadius.circular(30.0),
                                            ),
                                            hintText: "Password",
                                          ),
                                        ),
                                      ),
                                    ),
                                    Align(
                                      alignment: Alignment.bottomRight,
                                      child: Container(
                                          margin: EdgeInsets.only(
                                              top: 1, left: 10, right: 10),
                                          child: FlatButton(
                                            onPressed: () {
                                              Navigator.pushNamed(
                                                  context, "/password-reset");
                                            },
                                            child: Text("Forgot Password?",
                                                style: TextStyle(
                                                    fontFamily: 'Roboto-Medium',
                                                    fontSize: 14.0,
                                                    letterSpacing: 1.25,
                                                    color: Color.fromRGBO(
                                                        75, 56, 137, 80))),
                                          )),
                                    ),
                                    Container(
                                        margin: EdgeInsets.only(
                                            top: 1, left: 10, right: 10),
                                        child: SizedBox(
                                          width:
                                              MediaQuery.of(context).size.width * .90,
                                          child: RaisedButton(
                                            color: Color.fromRGBO(75, 56, 137, 80),
                                            textColor: Colors.white,
                                            shape: RoundedRectangleBorder(
                                                borderRadius:
                                                    new BorderRadius.circular(18.0),
                                                side: BorderSide(
                                                    color: Color.fromRGBO(
                                                        75, 56, 137, 80))),
                                            child: Text(
                                              "LOGIN",
                                              style:
                                                  Theme.of(context).textTheme.button,
                                            ),
                                            onPressed: () {
                                              String email = _phoneNumber.text;
                                              String password =
                                                  _passwordController.text;
      
                                              if (_formKey.currentState.validate()) {
                                                // loginProcess(email, password);
                                              }
                                            },
                                          ),
                                        ))
                                  ],
                                ),
                              ),
                              Container(
                                  margin:
                                      EdgeInsets.only(top: 1, left: 10, right: 10),
                                  child: FlatButton(
                                    onPressed: () {
                                      Navigator.pushNamed(context, "/register");
                                    },
                                    child: RichText(
                                      text: TextSpan(children: <TextSpan>[
                                        TextSpan(
                                          text: "Not a member yet? ",
                                          style: TextStyle(
                                              fontFamily: 'Roboto-Regular',
                                              fontSize: 14.0,
                                              letterSpacing: 0.25,
                                              color: Color.fromRGBO(75, 56, 137, 80)),
                                        ),
                                        TextSpan(
                                          text: "Create an Account",
                                          style: TextStyle(
                                            decoration: TextDecoration.underline,
                                            fontFamily: 'Roboto-Regular',
                                            fontSize: 14.0,
                                            letterSpacing: 0.25,
                                            color: Color.fromRGBO(75, 56, 137, 80),
                                          ),
                                        )
                                      ]),
                                    ),
                                  )),
                              SizedBox(height: 400),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              }),
            ),
          );
          //child: Image.asset("assets/images/login_image.png"),
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-01-17
        • 2012-06-27
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 2020-05-03
        • 1970-01-01
        相关资源
        最近更新 更多