我正在使用Flutter SDK和Dart制作一个移动应用程序,到目前为止,我只是得到了一个简单的用户登录表单,主要的小部件是一个ListView,顶部小部件是一个卡片小部件,里面有一个可以用作徽标的图像,我的问题是,这个徽标需要1到2秒的加载时间,看起来非常丑陋,我的意思是,当我启动应用程序时,在闪屏之后,我看到的卡片小部件上只有一个空白区域,1到2秒后我的图像出现,它非常明显。
我读了很多方法来避免这一点,但似乎没有一个工作,最常见的是使用precacheImage方法预加载图像,但似乎不起作用,我也尝试了这个内置的释放和同样的事情发生,我必须澄清,这个标志是非常小的尺寸(100kB)。
到目前为止,这是我的代码的一部分,这个HomeState类只是Home stateful小部件的状态,它是作为MaterialApp主页的Scaffold小部件的主体,这是主屏幕,所以在闪屏之后,这是加载的第一件事,
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
}
});
}),
)
],
),
),
),
);
}
}
发布于 2019-06-04 05:42:52
我的抽屉背景图像也有同样的问题,我用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");
发布于 2019-08-29 17:49:51
我有一个类似的问题,对我来说,我减少了图像从5000 x 5000到250 x 250,因为它们不会比应用程序文件中的大小从11mb到75kb,然后在Photoshop中我也将其导出为较小的文件(8位),使其类似于35kb。我会尝试jpeg,但我需要透明的背景!但文件大小的大规模减少对我很有帮助。
https://stackoverflow.com/questions/56434003
复制相似问题