Flutter非常简单的图像加载速度非常慢 [英] Very simple image loaded pretty slow with Flutter

查看:1182
本文介绍了Flutter非常简单的图像加载速度非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm making a mobile application using the Flutter SDK and Dart, so far, I just got a simple User login form, the main widget over that is a ListView with the top widget as a Card widget with an image inside that works as a logo, my problem is, this logo takes like 1 to 2 seconds to load, and looks very ugly, I mean, when I launch the app, after the splash screen, all I see over my Card widget is a blank space, and after 1 to 2 seconds my image appears, it is very noticeable.

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

I read many ways to avoid this but none seem to work, the most common is to use precacheImage method to preload the image but that doesn't seem to work, I also tried this over the built as release and same thing happen, I must clarify that this logo is very small in size (100kB).

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

So far this is a part of my code, this HomeState class is just State of the Home stateful widget that is the body of a Scaffold widget that is the home of a MaterialApp, this is the main screen, so after the splash screen this is the first thing that loads,

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)),
        ));
  }
}

UPDATE

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

As requested, here is my full code, they are three files.

main.dart:

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(加载图像的位置)

home.dart (place where the image is loaded)

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我认为这不是必需的,但是

And resgister.dart I think this is not needed but here it goes

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
                        }
                      });
                    }),
              )
            ],
          ),
        ),
      ),
    );
  }
}


推荐答案

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

I had the same problem with my drawer background image and I solved it with the precache Image, i guess you are using the precacheimage on the wrong place. you need to understand that in order to show the image correctly you need to load the image on app start and not till the state is initiated. try this:

 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(),只需在这样的定义上声明图像即可:

On the HomeState page you don't need to use didChangeDependencies(), just declare the image on the definition like this :

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

这篇关于Flutter非常简单的图像加载速度非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆