Flutter-适用于不同屏幕尺寸的自适应用户界面

时间:2019-07-04 22:48:28

标签: flutter media-queries flutter-layout

我试图弄清楚颤动的响应方式。因此,从图像中您可以看到,对于不同屏幕尺寸的iPhone来说,一切进展都不顺利。

我正在使用Stack和FractionallySizedBox,但是不确定我在做什么。任何帮助,谢谢。

代码在此处可用-> https://gist.github.com/GY22/1eefb5e48fdca9d785365cbccbdcb478

enter image description here

import 'package:flutter/material.dart';

class SignIn extends StatelessWidget {
    //textfields + logo
    List<Widget> _buildChildrenForm() {
        return [
            //logo
            Text(
                'THE GUEST LIST',
                style: TextStyle(
                    color: Colors.white,
                    fontFamily: 'futura',
                    fontSize: 60.0
                )
            ),
            //email
            TextField(
                cursorColor: Colors.white,
                cursorWidth: 3.0,
                decoration: InputDecoration(
                    enabledBorder: UnderlineInputBorder(
                            borderSide: BorderSide(
                                    color: Colors.white
                            )
                    ),
                    labelText: 'EMAIL',
                    labelStyle: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                    ),
                    //hintText: 'DEMO@MAIL.COM',
                    hintStyle: TextStyle(
                        fontSize: 20.0,
                        color: Colors.white,
                    ),
                ),
                style: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0
                ),
            ),
            SizedBox(height: 20.0,),
            //password
            TextField(
                cursorColor: Colors.white,
                cursorWidth: 3.0,
                obscureText: true,
                decoration: InputDecoration(
                    enabledBorder: UnderlineInputBorder(
                            borderSide: BorderSide(
                                    color: Colors.white
                            )
                    ),
                    labelText: 'PASSWORD',
                    labelStyle: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                    ),
                    hintStyle: TextStyle(
                            color: Colors.white
                    ),
                ),
                style: TextStyle(
                    color: Colors.white,
                ),
            ),
            SizedBox(height: 65.0,),
            //submit button
            FlatButton(
                child: Text(
                    'SIGN IN',
                    style: TextStyle(
                            fontSize: 35.0,
                            color: Colors.white
                    ),
                ),
                onPressed: () {},
            ),
            SizedBox(height: 10.0),
            //forget password
            FlatButton(
                child: Text(
                    'FORGOT PASSWORD',
                    style: TextStyle(
                            color: Colors.white,
                            fontSize: 17.0
                    ),
                ),
                onPressed: () {},
            )
        ];
    }

    Widget _formSignIn(BuildContext context) {
        return Padding(
            padding: const EdgeInsets.all(30.0),
            child: Column(
                children: _buildChildrenForm(),
            ),
        );
    }

    @override
    Widget build(BuildContext context) {
        final double screenHeight = MediaQuery.of(context).size.height;
        final double halfScreen = screenHeight / 2;
        final double finalHeight = halfScreen / screenHeight;
        debugPrint(MediaQuery.of(context).size.height.toString());
        //debugPrint(MediaQuery.of(context).size.width.toString());

        return Scaffold(
            body: Stack(
                fit: StackFit.expand,
                children: <Widget>[
                    //bg image
                    FractionallySizedBox(
                        alignment: Alignment.topLeft,
                      child: Container(
                        decoration: BoxDecoration(
                                image: DecorationImage(
                                        image: AssetImage('images/backgroundWithOpacity.png'),
                                        fit: BoxFit.cover
                                )
                        ),
                      ),
                    ),
                    //form
                    FractionallySizedBox(
                        alignment: Alignment.center,
                        heightFactor: 1 - finalHeight,
                        child: ListView(
                            children: <Widget>[
                                _formSignIn(context)
                            ],
                        ),
                    )
                ],
            ),




        );
    }
}

3 个答案:

答案 0 :(得分:1)

使用FittedBox压缩设备宽度中的标题。

使用Align进行居中,我们仅需要ListView来显示键盘外观,通常您想要显示给用户的内容对于iPhone 5s来说甚至还很小。

您还有多余的代码行,我已将其删除。

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: Scaffold(
    body: SignIn(),
  )));
}

class SignIn extends StatelessWidget {
  List<Widget> _buildChildrenForm() => [
        //logo
        SizedBox(
          width: double.infinity,
          child: FittedBox(
            fit: BoxFit.fitWidth,
            child: Text('THE GUEST LIST',
                style: TextStyle(
                    color: Colors.white, fontFamily: 'futura', fontSize: 60.0)),
          ),
        ),
        //email
        TextField(
          cursorColor: Colors.white,
          cursorWidth: 3.0,
          decoration: InputDecoration(
            enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.white)),
            labelText: 'EMAIL',
            labelStyle: TextStyle(
              color: Colors.white,
              fontSize: 20.0,
            ),
            //hintText: 'DEMO@MAIL.COM',
            hintStyle: TextStyle(
              fontSize: 20.0,
              color: Colors.white,
            ),
          ),
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        //password
        SizedBox(height: 20),
        TextField(
          cursorColor: Colors.white,
          cursorWidth: 3.0,
          obscureText: true,
          decoration: InputDecoration(
            enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.white)),
            labelText: 'PASSWORD',
            labelStyle: TextStyle(
              color: Colors.white,
              fontSize: 20.0,
            ),
            hintStyle: TextStyle(color: Colors.white),
          ),
          style: TextStyle(
            color: Colors.white,
          ),
        ),
        //submit button
        SizedBox(height: 65),
        FlatButton(
          child: Text(
            'SIGN IN',
            style: TextStyle(fontSize: 35.0, color: Colors.white),
          ),
          onPressed: () {},
        ),
        SizedBox(height: 10),
        //forget password
        FlatButton(
          child: Text(
            'FORGOT PASSWORD',
            style: TextStyle(color: Colors.white, fontSize: 17.0),
          ),
          onPressed: () {},
        )
      ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          //bg image
          FractionallySizedBox(
            alignment: Alignment.topLeft,
            child: Container(
              decoration: BoxDecoration(
                  image: DecorationImage(
                      image: AssetImage('assets/backgroundWithOpacity.png'),
                      fit: BoxFit.cover)),
            ),
          ),
          //form
          Align(
            alignment: Alignment.center,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 32.0),
              child: ListView(
                shrinkWrap: true,
                children: _buildChildrenForm(),
              ),
            ),
          )
        ],
      ),
    );
  }
}

答案 1 :(得分:0)

尽可能避免使用SizeConfig(自定义类)和硬编码尺寸。 例如:MediaQuery.of(context).size.width - someValue

制作Sizer插件是制作不同屏幕尺寸的响应式UI的最简单方法。

检查此插件⬇️
https://pub.dev/packages/sizer

答案 2 :(得分:0)

您可以使用 SingleChildScrollView 或 ListView,并使用相对比例