【问题标题】:How to make the flutter app responsive?如何使颤振应用程序响应?
【发布时间】:2018-11-07 16:35:56
【问题描述】:

我一直在尝试制作一个颤振应用程序(仍在学习),并且能够制作一个登录屏幕。但是,我注意到该应用程序没有响应。当我在模拟器上测试它时,它工作正常,但是当我将它安装到一个屏幕较小的手机上时,我注意到小部件并不小,所以手机无法一次显示整个屏幕。有人可以帮我制作这个应用程序响应式,以便它适合任何尺寸的屏幕吗?

我的完整代码如下;

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  final TextEditingController _usernameController = new TextEditingController();
  final TextEditingController _passwordController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    void printSomething(){
      print("Something was printed");
    }

    Widget buttonSection = new Container(
      padding: new EdgeInsets.all(32.0),
      child: new Row(
        children: [
          new Expanded(
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                new MaterialButton(
                  child: new Text(
                    "Sign In", 
                    style: new TextStyle(
                      color: Colors.white,
                      fontSize: 20.0
                      ),
                    ),
                  onPressed: (){printSomething();},
                  height: 50.0,
                  minWidth: 400.0,
                  color: Colors.blueAccent,
                ),

                SizedBox(height: 10.0),

                new MaterialButton(
                  child: new Text(
                    "Sign Up",
                    style: new TextStyle(
                      color: Colors.white,
                      fontSize: 20.0
                      ),
                    ),
                  onPressed: null,
                  height: 50.0,
                  minWidth: 400.0,
                  color: Colors.blueAccent,
                )
              ],
            ),
          ),
        ],
      ),
    );

    Widget textFieldSection = new Container(
      padding: new EdgeInsets.all(32.0),
      child: new Row(
        children: [
          new Expanded(
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                new TextField(
                  autocorrect: false,
                  obscureText: false,
                  controller: _usernameController,
                  maxLines: 1,
                  decoration: new InputDecoration(
                    hintText: "Username",
                    icon: new Icon(Icons.person),
                  ),

                  style: new TextStyle(
                    fontSize: 20.0,
                    color: Colors.black
                  ),
                ),

                new SizedBox(height: 10.0),

                new TextField(
                  autocorrect: false,
                  obscureText: true,
                  controller: _passwordController,
                  maxLines: 1,
                  decoration: new InputDecoration(
                    hintText: "Password",
                    icon: new Icon(Icons.vpn_key),
                  ),

                  style: new TextStyle(
                    fontSize: 20.0,
                    color: Colors.black
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );

    Widget titleSection = new Container(
      padding: new EdgeInsets.all(32.0),
      child: new Row(
        children: [
          new Expanded(
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                new Container(
                  padding: const EdgeInsets.only(bottom: 8.0),
                  child: new Text(
                    "Please login using your credentials",
                    style: new TextStyle(
                      fontSize: 20.0,
                      fontWeight: FontWeight.bold
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );

    return new MaterialApp(
      title: "Service",
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),

      home: new Scaffold(
        body: new ListView(
          reverse: true,
          children: [
            SizedBox(height: 30.0),
            new Image.asset(
              'assets/logo.png',
              height: 200.0,
            ),
            titleSection,
            textFieldSection,
            buttonSection
          ].reversed.toList(),
        ),
      ),
    );
  }
}

【问题讨论】:

标签: android mobile dart flutter


【解决方案1】:

我创建了一篇关于 Flutter 响应式 UI 的详细文章,希望对您有所帮助

TDLR(来自帖子):

  1. 在响应式 UI 中,我们不使用硬编码的尺寸值和 职位。使用MediaQuery获取窗口的实时大小。

  2. 使用 FlexibleExpanded 小部件获得灵活的 UI 使用百分比而不是硬编码值。

  3. 使用LayoutBuilder获取父widget的ConstraintBox

  4. 您可以使用MediaQueryOrientationBuilder.

【讨论】:

  • 太棒了。谢谢:)
【解决方案2】:

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

在任何屏幕尺寸的设备以及平板电脑上都具有响应式 UI。看看这个插件⬇️
https://pub.dev/packages/sizer

.h  - for widget height
.w  - for widget width
.sp - for font size

在这样的值之后使用.h.w.sp ⬇️

例子:

Container(
  height: 10.0.h,  //10% of screen height
  width: 80.0.w,   //80% of screen width
  child: Text('Sizer', style: TextStyle(fontSize: 12.0.sp)),
);

我已经用这个插件构建了许多响应式 UI。

【讨论】:

    【解决方案3】:

    尝试以下方法:

    1. 尽可能避免硬编码尺寸。

    2. 如果您无法避免将宽度或高度固定为某个值,请尝试使用实际屏幕尺寸计算该值。 例子: MediaQuery.of(context).size.width - someValue

    3. 使用已有的属性而不是固定宽度和高度。示例:

      a. crossAxisAlignment:CrossAxisAlignment.stretch 用于将您的按钮拉伸到全屏尺寸而不是 minWidth: 400.0

      b. 填充:const EdgeInsets.symmetric(vertical: 12.0),用于按钮垂直填充,而不是 height: 50.0

    【讨论】:

      【解决方案4】:

      使用方向

      double width, height;
      
      if (MediaQuery.of(context).orientation == Orientation.landscape){
        width = MediaQuery.of(context).size.width * 0.25; // width = 25% of the screen
        height = MediaQuery.of(context).size.height * 0.25; //height = 25% of the screen 
      }
      else{
        width = MediaQuery.of(context).size.width * 0.10; // width = 10% of the screen
        height = MediaQuery.of(context).size.height * 0.10; //height = 10% of the screen 
      }
      
      child: Padding(
              padding: EdgeInsets.symmetric(horizontal: width),
             )
      
      or
      
      child: Container(
            width: width;
            height: height;
            ), 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-12
        • 2020-08-10
        • 2020-01-26
        • 2018-12-16
        • 2018-10-19
        • 2020-07-03
        • 1970-01-01
        • 2019-05-15
        相关资源
        最近更新 更多