Flutter 按住启动画面 3 秒。如何在 Flutter 中实现闪屏?
Flutter hold splash screen for 3 Seconds. How to implement splash screen in Flutter?
如何在 flutter 中显示闪屏 3 秒,然后转到下一个登录屏幕。
我有 tried.countdowntimer 但导入未解决
import 'package: countDown/countDown.dart';
CountDown cd = new CountDown(new Duration(seconds: 4));
CountDown is unresolved
Android Studio 和 Flutter
您可以使用 Future.delayed
延迟执行代码
new Future.delayed(const Duration(seconds: 3), () {
Navigator.pushNamed(context, '/login');
});
更新
const delay = 3;
widget.countdown = delay;
StreamSubscription sub;
sub = new Stream.periodic(const Duration(seconds: 1), (count) {
setState(() => widget.countdown--);
if(widget.countdown <= 0) {
sub.cancel();
Navigator.pushNamed(context, '/login');
}
});
Future.delayed
将是一个很好的解决方案 没有 倒计时。
但是考虑到你有一个倒计时,你可以使用 Flutter 提供的动画框架。
其背后的想法是使用持续时间为 3 秒的 AnimationController
。 splashScreen 实例化后立即启动动画。并添加一个侦听器以在动画结束时重定向到 /login
。
然后将该控制器传递给 AnimationBuilder
,它将根据 animationController.lastElaspedDuration
.
处理倒计时的格式
class SplashScreen extends StatefulWidget {
final Duration duration;
const SplashScreen({this.duration});
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
animationController = new AnimationController(duration: widget.duration, vsync: this)
..forward()
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
Navigator.pushReplacementNamed(context, '/login');
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return new AnimatedBuilder(
animation: animationController,
builder: (context, _) {
return new Center(
child: new Text(animationController.lastElapsedDuration.inSeconds.toString()),
);
},
);
}
}
我认为您需要从堆栈(启动画面)中清除旧的 activity,因此您必须使用 pushNamedAndRemoveUntil
而不是仅使用 pushNamed
。
new Future.delayed(const Duration(seconds: 3), () {
Navigator.pushNamedAndRemoveUntil(context, '/login', ModalRoute.withName('/'));
});
参考下面main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'src/login_screen.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
new Future.delayed(
const Duration(seconds: 3),
() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
body: Container(
child: new Column(children: <Widget>[
Divider(
height: 240.0,
color: Colors.white,
),
new Image.asset(
'assets/logo.png',
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
width: 170.0,
),
Divider(
height: 105.2,
color: Colors.white,
),
]),
),
);
}
}
希望对您有所帮助
此答案仅适用于您使用 flutter-redux
.
的情况
与 flutter-redux
一起,您需要使用 redux-persist
库来显示加载屏幕。
redux-persist
用于存储、补充应用程序状态。
示例:
1.main.dart
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux_persist_flutter/redux_persist_flutter.dart';
import 'package:flutter_redux_starter/presentation/platform_adaptive.dart';
import 'package:flutter_redux_starter/screens/loading_screen.dart';
import 'package:flutter_redux_starter/store/store.dart';
import 'package:flutter_redux_starter/middleware/middleware.dart';
import 'package:flutter_redux_starter/models/app_state.dart';
import 'package:flutter_redux_starter/routes.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
final store = createStore();
MyApp();
@override
Widget build(BuildContext context) {
return new PersistorGate(
persistor: persistor,
loading: new LoadingScreen(),
builder: (context) => new StoreProvider<AppState>(
store: store,
child: new MaterialApp(
title: 'Flutter test App',
theme: defaultTargetPlatform == TargetPlatform.iOS
? kIOSTheme
: kDefaultTheme,
routes: getRoutes(context, store),
initialRoute: '/login',
)
),
);
}
}
2.store.dart
import 'package:redux/redux.dart';
import 'package:flutter_redux_starter/reducers/app_reducer.dart';
import 'package:flutter_redux_starter/models/app_state.dart';
import 'package:flutter_redux_starter/middleware/middleware.dart';
Store<AppState> createStore() {
Store<AppState> store = new Store(
appReducer,
initialState: new AppState(),
middleware: createMiddleware(),
);
persistor.start(store);
return store;
}
在 createStore 中,您可以使用 Future.delayed 将商店的创建延迟一定秒数。
new Future.delayed(const Duration(seconds: 3), () {
//
});
您可以在 initState
中使用 Future.delayed
构造函数。这将使您的 SplashScreen 在导航发生之前的指定时间内保持不变。
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState (){
super.initState();
// TODO initial state stuff
new Future.delayed(const Duration(seconds: 4));
}
@override
Widget build(BuildContext context) {
//build
}
}
我只复制了答案:
Simple solution which i use in every app.
在构建方法中使用Timer
class
代码片段
class SplashScreen extends StatefulWidget {
@override
Splash createState() => Splash();
}
class Splash extends State<SplashScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Timer(
Duration(seconds: 3),
() =>
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LandingScreen())));
var assetsImage = new AssetImage(
'images/new_logo.png'); //<- Creates an object that fetches an image.
var image = new Image(
image: assetsImage,
height:300); //<- Creates a widget that displays an image.
return MaterialApp(
home: Scaffold(
/* appBar: AppBar(
title: Text("MyApp"),
backgroundColor:
Colors.blue, //<- background color to combine with the picture :-)
),*/
body: Container(
decoration: new BoxDecoration(color: Colors.white),
child: new Center(
child: image,
),
), //<- place where the image appears
),
);
}
}
我需要一个延迟 5 秒的小部件。我的解决方案如下:
class Waiting extends StatefulWidget {
@override
_WaitingState createState() => _WaitingState();
}
class _WaitingState extends State<Waiting> {
bool voxt = false;
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.delayed(Duration(seconds: 3)),
builder: (c, s) => s.connectionState != ConnectionState.done
? Text('Waiting')
: Text('3 sec passed')
);
}
}
现在可以在需要的地方调用等待 小部件。
最简洁的方法,无需添加显式计时器。
使用基于时间的SplashScreen
。
class TimeBasedSplash extends State<MyApp>{
@override
Widget build(BuildContext context) {
return new SplashScreen(
seconds: 10,
navigateAfterSeconds: new HomeScreen(),// Where to navigate after 10 secs
image: new Image.asset('assets/images/flutter_logo.png'),
photoSize: 200,
loaderColor: Colors.white,
styleTextUnderTheLoader : const TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold, color: Colors.white),
loadingText: new Text('Loading...'),
gradientBackground: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Colors.lightBlue,
Colors.indigo
],
),
);
}
}
主要class
void main(){
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new TimeBasedSplash().build(context);
}
}
您还可以在 StatlessWidget()
中创建 splashScreen
。 MaterialApp()
下家里面:
home: FutureBuilder(
future: Future.delayed(Duration(seconds: 3)),
builder: (ctx, timer) => timer.connectionState == ConnectionState.done
? ProfileScreen() //Screen to navigate to once the splashScreen is done.
: Container(
color: Colors.white,
child: Image(
image: AssetImage('assets/images/download.png'),
),
)),
如何在 flutter 中显示闪屏 3 秒,然后转到下一个登录屏幕。
我有 tried.countdowntimer 但导入未解决
import 'package: countDown/countDown.dart';
CountDown cd = new CountDown(new Duration(seconds: 4));
CountDown is unresolved
Android Studio 和 Flutter
您可以使用 Future.delayed
new Future.delayed(const Duration(seconds: 3), () {
Navigator.pushNamed(context, '/login');
});
更新
const delay = 3;
widget.countdown = delay;
StreamSubscription sub;
sub = new Stream.periodic(const Duration(seconds: 1), (count) {
setState(() => widget.countdown--);
if(widget.countdown <= 0) {
sub.cancel();
Navigator.pushNamed(context, '/login');
}
});
Future.delayed
将是一个很好的解决方案 没有 倒计时。
但是考虑到你有一个倒计时,你可以使用 Flutter 提供的动画框架。
其背后的想法是使用持续时间为 3 秒的 AnimationController
。 splashScreen 实例化后立即启动动画。并添加一个侦听器以在动画结束时重定向到 /login
。
然后将该控制器传递给 AnimationBuilder
,它将根据 animationController.lastElaspedDuration
.
class SplashScreen extends StatefulWidget {
final Duration duration;
const SplashScreen({this.duration});
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderStateMixin {
AnimationController animationController;
@override
void initState() {
animationController = new AnimationController(duration: widget.duration, vsync: this)
..forward()
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
Navigator.pushReplacementNamed(context, '/login');
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return new AnimatedBuilder(
animation: animationController,
builder: (context, _) {
return new Center(
child: new Text(animationController.lastElapsedDuration.inSeconds.toString()),
);
},
);
}
}
我认为您需要从堆栈(启动画面)中清除旧的 activity,因此您必须使用 pushNamedAndRemoveUntil
而不是仅使用 pushNamed
。
new Future.delayed(const Duration(seconds: 3), () {
Navigator.pushNamedAndRemoveUntil(context, '/login', ModalRoute.withName('/'));
});
参考下面main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'src/login_screen.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
new Future.delayed(
const Duration(seconds: 3),
() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
body: Container(
child: new Column(children: <Widget>[
Divider(
height: 240.0,
color: Colors.white,
),
new Image.asset(
'assets/logo.png',
fit: BoxFit.cover,
repeat: ImageRepeat.noRepeat,
width: 170.0,
),
Divider(
height: 105.2,
color: Colors.white,
),
]),
),
);
}
}
希望对您有所帮助
此答案仅适用于您使用 flutter-redux
.
与 flutter-redux
一起,您需要使用 redux-persist
库来显示加载屏幕。
redux-persist
用于存储、补充应用程序状态。
示例:
1.main.dart
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux_persist_flutter/redux_persist_flutter.dart';
import 'package:flutter_redux_starter/presentation/platform_adaptive.dart';
import 'package:flutter_redux_starter/screens/loading_screen.dart';
import 'package:flutter_redux_starter/store/store.dart';
import 'package:flutter_redux_starter/middleware/middleware.dart';
import 'package:flutter_redux_starter/models/app_state.dart';
import 'package:flutter_redux_starter/routes.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
final store = createStore();
MyApp();
@override
Widget build(BuildContext context) {
return new PersistorGate(
persistor: persistor,
loading: new LoadingScreen(),
builder: (context) => new StoreProvider<AppState>(
store: store,
child: new MaterialApp(
title: 'Flutter test App',
theme: defaultTargetPlatform == TargetPlatform.iOS
? kIOSTheme
: kDefaultTheme,
routes: getRoutes(context, store),
initialRoute: '/login',
)
),
);
}
}
2.store.dart
import 'package:redux/redux.dart';
import 'package:flutter_redux_starter/reducers/app_reducer.dart';
import 'package:flutter_redux_starter/models/app_state.dart';
import 'package:flutter_redux_starter/middleware/middleware.dart';
Store<AppState> createStore() {
Store<AppState> store = new Store(
appReducer,
initialState: new AppState(),
middleware: createMiddleware(),
);
persistor.start(store);
return store;
}
在 createStore 中,您可以使用 Future.delayed 将商店的创建延迟一定秒数。
new Future.delayed(const Duration(seconds: 3), () {
//
});
您可以在 initState
中使用 Future.delayed
构造函数。这将使您的 SplashScreen 在导航发生之前的指定时间内保持不变。
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState (){
super.initState();
// TODO initial state stuff
new Future.delayed(const Duration(seconds: 4));
}
@override
Widget build(BuildContext context) {
//build
}
}
我只复制了答案:
Simple solution which i use in every app.
在构建方法中使用Timer
class
代码片段
class SplashScreen extends StatefulWidget {
@override
Splash createState() => Splash();
}
class Splash extends State<SplashScreen> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
Timer(
Duration(seconds: 3),
() =>
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LandingScreen())));
var assetsImage = new AssetImage(
'images/new_logo.png'); //<- Creates an object that fetches an image.
var image = new Image(
image: assetsImage,
height:300); //<- Creates a widget that displays an image.
return MaterialApp(
home: Scaffold(
/* appBar: AppBar(
title: Text("MyApp"),
backgroundColor:
Colors.blue, //<- background color to combine with the picture :-)
),*/
body: Container(
decoration: new BoxDecoration(color: Colors.white),
child: new Center(
child: image,
),
), //<- place where the image appears
),
);
}
}
我需要一个延迟 5 秒的小部件。我的解决方案如下:
class Waiting extends StatefulWidget {
@override
_WaitingState createState() => _WaitingState();
}
class _WaitingState extends State<Waiting> {
bool voxt = false;
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.delayed(Duration(seconds: 3)),
builder: (c, s) => s.connectionState != ConnectionState.done
? Text('Waiting')
: Text('3 sec passed')
);
}
}
现在可以在需要的地方调用等待 小部件。
最简洁的方法,无需添加显式计时器。
使用基于时间的SplashScreen
。
class TimeBasedSplash extends State<MyApp>{
@override
Widget build(BuildContext context) {
return new SplashScreen(
seconds: 10,
navigateAfterSeconds: new HomeScreen(),// Where to navigate after 10 secs
image: new Image.asset('assets/images/flutter_logo.png'),
photoSize: 200,
loaderColor: Colors.white,
styleTextUnderTheLoader : const TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold, color: Colors.white),
loadingText: new Text('Loading...'),
gradientBackground: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Colors.lightBlue,
Colors.indigo
],
),
);
}
}
主要class
void main(){
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new TimeBasedSplash().build(context);
}
}
您还可以在 StatlessWidget()
中创建 splashScreen
。 MaterialApp()
下家里面:
home: FutureBuilder(
future: Future.delayed(Duration(seconds: 3)),
builder: (ctx, timer) => timer.connectionState == ConnectionState.done
? ProfileScreen() //Screen to navigate to once the splashScreen is done.
: Container(
color: Colors.white,
child: Image(
image: AssetImage('assets/images/download.png'),
),
)),