Flutter

时间:2019-06-03 20:17:24

标签: flutter dart

我正在使用Flutter SDK和Dart制作移动应用程序,到目前为止,我只获得了一个简单的用户登录表单,其上方的主要小部件是一个ListView,顶部的小部件为Card小部件,其中包含图像。用作徽标,我的问题是,加载此徽标大约需要1到2秒钟,而且看起来非常难看。我的意思是,当我启动应用程序时,在启动屏幕之后,我在Card小部件上看到的全部是空白,然后在1到2秒钟后出现我的图片,非常引人注目。

我阅读了很多方法来避免这种情况,但是似乎没有任何效果,最常见的方法是使用precacheImage方法来预加载图像,但是那似乎不起作用,我还尝试了在构建版本时进行此操作,并且发生了同样的事情,我必须澄清这个徽标的尺寸非常小(100kB)。

到目前为止,这是我代码的一部分,该HomeState类只是Home状态小部件的State,该状态小部件是Scaffold小部件的主体,而Scaffold小部件是MaterialApp的宿主,这是主屏幕,因此在启动后屏幕上这是加载的第一件事,

class HomeState extends State<Home> {
  var _minPad = 5.0;
  var _formKey = GlobalKey<FormState>();
  TextEditingController username = TextEditingController();
  TextEditingController password = TextEditingController();
  ImageProvider logo;

  @override
  void didChangeDependencies() async {
    logo = AssetImage('images/logo_rienpa.png');
    await precacheImage(logo, context);
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Center(
              child: Text('Rutinas de Mantenimiento',
                  textAlign: TextAlign.center))),
      body: loginForm(),
      backgroundColor: Colors.blue,
    );
  }

  Form loginForm() {
    TextStyle titleStyle = Theme.of(context).textTheme.title;
    return Form(
        key: _formKey,
        child: Padding(
          padding: EdgeInsets.all(_minPad * 4),
          child: Center(
            child: ListView(
              children: <Widget>[
                getLogo(),
                Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 8, bottom: _minPad * 2),
                    child: TextFormField(
                      controller: username,
                      keyboardType: TextInputType.text,
                      style: titleStyle,
                      validator: (String value) {
                        if (value.isEmpty) {
                          return 'Por favor, ingresa tu nombre de usuario';
                        }
                      },
                      decoration: InputDecoration(
                          labelText: 'Usuario',
                          labelStyle: titleStyle,
                          hintText: 'Ingresa tu usuario',
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(5.0))),
                    )),
                Padding(
                  padding:
                      EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 4),
                  child: TextFormField(
                    controller: password,
                    obscureText: true,
                    style: titleStyle,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor, ingresa una contraseña';
                      }
                    },
                    decoration: InputDecoration(
                        labelText: 'Contraseña',
                        labelStyle: titleStyle,
                        hintText: 'Contraseña personal',
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(5.0))),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(
                      top: _minPad * 2,
                      bottom: _minPad * 2,
                      right: _minPad * 20,
                      left: _minPad * 20),
                  child: RaisedButton(
                      color: Theme.of(context).primaryColor,
                      textColor: Colors.white,
                      child: Text(
                        "Ingresar",
                        textScaleFactor: 1.5,
                      ),
                      onPressed: () {
                        setState(() {
                          if (_formKey.currentState.validate()) {
                            //code
                          }
                        });
                      }),
                ),
                Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 10, bottom: _minPad * 2),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          "No tienes un usuario?, registrate ",
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.white),
                        ),
                        InkWell(
                          child: Text(
                            'aqui',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                                color: Colors.black,
                                decoration: TextDecoration.underline),
                          ),
                          onTap: () {
                            Navigator.push(context,
                                MaterialPageRoute(builder: (context) {
                              return Register();
                            }));
                          },
                        ),
                        Text(
                          ".",
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.white),
                        )
                      ],
                    ))
              ],
            ),
          ),
        ));
  }

  Widget getLogo() {
    Image logoImage = Image(image: logo, width: 250.0, height: 167.0,);
    return Padding(
        padding: EdgeInsets.only(right: _minPad * 5, left: _minPad * 5),
        child: Card(
          color: Colors.white,
          elevation: 8.0,
          child: logoImage,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
        ));
  }
}

更新

根据要求,这是我的完整代码,它们是三个文件。

main.dart:

import 'package:flutter/material.dart';
import 'package:rutinas_de_mantenimiento/screens/home.dart';

void main() => runApp(MainApp());

class MainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    precacheImage(AssetImage('images/logo_rienpa.png'), context);
    return MaterialApp(
      title: "Rutinas de Mantenimiento",
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          primarySwatch: Colors.blueGrey, primaryColor: Colors.blueGrey),
      home: Home(),
    );
  }
}

home.dart(加载图像的地方)

import 'package:flutter/material.dart';
import 'package:rutinas_de_mantenimiento/screens/register.dart';

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return HomeState();
  }
}

class HomeState extends State<Home> {
  var _minPad = 5.0;
  var _formKey = GlobalKey<FormState>();
  TextEditingController username = TextEditingController();
  TextEditingController password = TextEditingController();
  ImageProvider logo = AssetImage('images/logo_rienpa.png');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Center(
              child: Text('Rutinas de Mantenimiento',
                  textAlign: TextAlign.center))),
      body: loginForm(),
      backgroundColor: Colors.blue,
    );
  }

  Form loginForm() {
    TextStyle titleStyle = Theme.of(context).textTheme.title;
    return Form(
        key: _formKey,
        child: Padding(
          padding: EdgeInsets.all(_minPad * 4),
          child: Center(
            child: ListView(
              children: <Widget>[
                getLogo(),
                Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 8, bottom: _minPad * 2),
                    child: TextFormField(
                      controller: username,
                      keyboardType: TextInputType.text,
                      style: titleStyle,
                      validator: (String value) {
                        if (value.isEmpty) {
                          return 'Por favor, ingresa tu nombre de usuario';
                        }
                      },
                      decoration: InputDecoration(
                          labelText: 'Usuario',
                          labelStyle: titleStyle,
                          hintText: 'Ingresa tu usuario',
                          border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(5.0))),
                    )),
                Padding(
                  padding:
                      EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 4),
                  child: TextFormField(
                    controller: password,
                    obscureText: true,
                    style: titleStyle,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Por favor, ingresa una contraseña';
                      }
                    },
                    decoration: InputDecoration(
                        labelText: 'Contraseña',
                        labelStyle: titleStyle,
                        hintText: 'Contraseña personal',
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(5.0))),
                  ),
                ),
                Padding(
                  padding: EdgeInsets.only(
                      top: _minPad * 2,
                      bottom: _minPad * 2,
                      right: _minPad * 20,
                      left: _minPad * 20),
                  child: RaisedButton(
                      color: Theme.of(context).primaryColor,
                      textColor: Colors.white,
                      child: Text(
                        "Ingresar",
                        textScaleFactor: 1.5,
                      ),
                      onPressed: () {
                        setState(() {
                          if (_formKey.currentState.validate()) {
                            //code
                          }
                        });
                      }),
                ),
                Padding(
                    padding:
                        EdgeInsets.only(top: _minPad * 10, bottom: _minPad * 2),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          "No tienes un usuario?, registrate ",
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.white),
                        ),
                        InkWell(
                          child: Text(
                            'aqui',
                            textAlign: TextAlign.center,
                            style: TextStyle(
                                color: Colors.black,
                                decoration: TextDecoration.underline),
                          ),
                          onTap: () {
                            Navigator.push(context,
                                MaterialPageRoute(builder: (context) {
                              return Register();
                            }));
                          },
                        ),
                        Text(
                          ".",
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.white),
                        )
                      ],
                    ))
              ],
            ),
          ),
        ));
  }

  Widget getLogo() {
    Image logoImage = Image(image: logo, width: 250.0, height: 167.0,);
    return Padding(
        padding: EdgeInsets.only(right: _minPad * 5, left: _minPad * 5),
        child: Card(
          color: Colors.white,
          elevation: 8.0,
          child: logoImage,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
        ));
  }
}

还有resgister.dart,我认为这不是必需的,但是就可以了

import 'package:flutter/material.dart';

class Register extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return RegisterState();
  }
}

class RegisterState extends State<Register> {
  var _formKey = GlobalKey<FormState>();
  TextEditingController fullName = TextEditingController();
  TextEditingController username = TextEditingController();
  TextEditingController password = TextEditingController();
  TextEditingController confirmPwd = TextEditingController();
  TextEditingController email = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
          child: Text(
            'Rutinas de Mantenimiento',
            textAlign: TextAlign.center,
          ),
        ),
        automaticallyImplyLeading: false,
      ),
      body: registerForm(),
      backgroundColor: Colors.blue,
    );
  }

  Form registerForm() {
    var _minPad = 5.0;
    TextStyle titleStyle = Theme.of(context).textTheme.title;

    return Form(
      key: _formKey,
      child: Padding(
        padding: EdgeInsets.all(_minPad * 4),
        child: Center(
          child: ListView(
            children: <Widget>[
              Text(
                "Registro de usuario",
                textAlign: TextAlign.center,
                style: TextStyle(
                    decoration: null,
                    fontSize: 35.0,
                    color: Colors.white),
              ),
              Padding(
                padding:
                EdgeInsets.only(top: _minPad * 14, bottom: _minPad * 2),
                child: TextFormField(
                  controller: fullName,
                  style: titleStyle,
                  textAlign: TextAlign.center,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return 'Por favor ingresa tu nombre completo';
                    }
                  },
                  decoration: InputDecoration(
                      hintText: "Nombre completo", hintStyle: titleStyle),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                child: TextFormField(
                  controller: username,
                  style: titleStyle,
                  textAlign: TextAlign.center,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return 'Por favor ingresa un usuario';
                    }
                  },
                  decoration: InputDecoration(
                      hintText: "Nombre de usuario", hintStyle: titleStyle),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                child: TextFormField(
                  controller: email,
                  style: titleStyle,
                  textAlign: TextAlign.center,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return 'Por favor ingresa tu Email';
                    }
                  },
                  decoration:
                  InputDecoration(hintText: "Email", hintStyle: titleStyle),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                child: TextFormField(
                  controller: password,
                  obscureText: true,
                  style: titleStyle,
                  textAlign: TextAlign.center,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return 'Por favor ingresa una contraseña';
                    }
                  },
                  decoration: InputDecoration(
                      hintText: "Contraseña", hintStyle: titleStyle),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: _minPad * 2, bottom: _minPad * 2),
                child: TextFormField(
                  controller: confirmPwd,
                  obscureText: true,
                  style: titleStyle,
                  textAlign: TextAlign.center,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return 'Por favor repita su contraseña';
                    }
                  },
                  decoration: InputDecoration(
                      hintText: "Confirme contraseña", hintStyle: titleStyle),
                ),
              ),
              Padding(
                padding: EdgeInsets.only(
                    top: _minPad * 4,
                    bottom: _minPad * 2,
                    right: _minPad * 20,
                    left: _minPad * 20),
                child: RaisedButton(
                    color: Theme.of(context).primaryColor,
                    textColor: Colors.white,
                    child: Text(
                      "Registrar",
                      textScaleFactor: 1.5,
                    ),
                    onPressed: () {
                      setState(() {
                        if (_formKey.currentState.validate()) {
                          //code
                        }
                      });
                    }),
              )
            ],
          ),
        ),
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:1)

我的抽屉背景图像有相同的问题,我用precache图像解决了,我想您在错误的地方使用了precacheimage。您需要了解,为了正确显示图像,您需要在应用启动时而不是在启动状态之前加载图像。 试试这个:

 class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    precacheImage(AssetImage("images/logo_rienpa.png"), context);
    return MaterialApp(
      title: 'Fethi',
      theme: ThemeData(
        primarySwatch: Colors.lightBlue,
      ),
      home: new HomeState(),
    );
  }
}

在HomeState页面上,您不需要使用didChangeDependencies(),只需在定义中声明图像即可,如下所示:

 ImageProvider logo = AssetImage("images/logo_rienpa.png");

答案 1 :(得分:0)

我有一个类似的问题,对我来说,我将图像从5000 x 5000缩小到250 x 250,因为它们的大小不比应用程序文件中的大小从11mb增大到75kb,然后在Photoshop中我也将其导出为一个较小的文件(8位),大约35kb。我会尝试jpeg的,但是我需要透明的背景!但是文件大小的大量减少对我有所帮助。