i have a book for flutter beginner programmer. At the first section it show me how to create splash screen, but the problem is that splash screen is doesn't show, just a blank black screen and after that the apps is showing.
This is my splash_screen.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:wisata_yogya/main.dart';
void main() =>runApp(SplashScreen());
// ignore: use_key_in_widget_constructors
class SplashScreen extends StatelessWidget{
#override
Widget build(BuildContext context){
return MaterialApp(
home: _SplashScreenBody(),
);
}
}
class _SplashScreenBody extends StatefulWidget{
#override
State<StatefulWidget> createState(){
return _SplashScreenBodyState();
}
}
class _SplashScreenBodyState extends State<_SplashScreenBody>{
#override
Widget build(BuildContext context){
Future.delayed(const Duration(seconds: 3), (){
Navigator.pushAndRemoveUntil(context,
// ignore: prefer_const_constructors
MaterialPageRoute(builder: (context) => MyApp()), (Route route) => false);
});
return const Scaffold(
body: Center(
child: Image(
image: AssetImage("graphics/logo.png"),
height: 75,
width: 75,
)
)
);
}
}
And there's no error in the code.
Method 1
You can use animated_splash_screen its easy to use,
home: AnimatedSplashScreen(
splash: Scaffold(
body: Center(
child: Image.asset(
'assets/logo.png',
width: double.infinity,
height: double.infinity,
),
),
),
duration: 100,
nextScreen: Login(),
splashTransition: SplashTransition.fadeTransition,
backgroundColor: Colors.white,
Method 2
Or Use Timer for delay some seconds in the initState()
Timer(
Duration(seconds: 2),
() => Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage())));
class _SplashState extends State<Splash> {
#override
void initState() {
super.initState();
Timer(Duration(seconds: 3),
()=>Navigator.pushReplacement(context,
MaterialPageRoute(builder:
(context) =>First()
)
)
);
}
return Scaffold(
body: SizedBox.expand(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Image.asset('Assets/Group.png'),
padding: const EdgeInsets.all(8.0),
height: 200,
width: 200,
),
CircularProgressIndicator(color: HexColor('#22178F'),),
],
),
),
);
Try to add timer in initState instead of what you doing something like this
void initState() {
super.initState();
Timer(Duration(seconds: 5),
()=>Navigator.pushReplacement(context,
MaterialPageRoute(builder:
(context) => HomeScreen()
)
)
);
}
Related
Is it possible to have floating button visible throughout the life cycle of the app on top of all pages? I know that with Scaffold I can have it but it only works for that page and i'll lose it once I push a new page on the navigator stack.
Yes, OverlayEntry is made for this purpose.
To insert it, you can do something like this:
ElevatedButton(
child: Text("Overlay Test"),
onPressed: () {
final entry = OverlayEntry(
builder: (context) => Container(
color: Colors.blue,
),
);
Overlay.of(context)?.insert(entry);
},
)
If you want to remove it later, you can save the entry variable and then call entry.remove() when needed.
Full example:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
OverlayEntry? _entry;
double _left = 50;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OverlayEntry Demo"),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
child: Text("Add OverlayEntry"),
onPressed: () {
_entry = OverlayEntry(
builder: (context) {
print("build");
return Positioned(
left: _left,
top: 200,
child: Container(
width: 150,
height: 150,
color: Colors.grey,
),
);
},
);
Overlay.of(context)?.insert(_entry!);
},
),
ElevatedButton(
child: Text("Move it"),
onPressed: () {
_left += 10;
_entry?.markNeedsBuild();
},
),
ElevatedButton(
child: Text("Remove it"),
onPressed: () => _entry?.remove(),
),
],
),
),
);
}
}
One option is to use the builder of the MaterialApp to create a Stack with your Button on top:
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test',
home: TestPage(),
initialRoute: "/test",
builder: (context, child) {
return Scaffold(
body: Stack(
children: [
child!,
Positioned(
left: 0,
bottom: 0,
child: **your button here**,
),
],
),
);
},
routes: routes(context),
);
}
}
I want to use Splash in my app but when I use, I face such a problem MissingPluginException: No implementation found for method. However, when I write flutter run in terminal. I can see that it ignore something and show me splash and after it. But I want to work with debug. Here is my cod;
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:news/UI/wrapper.dart';
class Splash extends StatefulWidget {
#override
_SplashState createState() => _SplashState();
}
class _SplashState extends State<Splash> with SingleTickerProviderStateMixin {
SpinKitCubeGrid spinkit;
#override
void initState() {
super.initState();
spinkit = SpinKitCubeGrid(
color: Colors.white,
size: 50.0,
controller: AnimationController(
vsync: this, duration: const Duration(milliseconds: 3000)),
);
new Future.delayed(
const Duration(seconds: 3),
() => Navigator.push(
context,
MaterialPageRoute(builder: (context) => Wrapper()),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromRGBO(240, 100, 0, 1),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
spinkit,
SizedBox(
height: 25,
),
Text(
"Hoşgeldin",
style: GoogleFonts.nunito(fontSize: 20),
),
],
),
),
);
}
}
I have wrapped the body of the code below using GestureDetector, thus enabling me to use onVerticalDragEnd method available in the widget. When the app detects a Vertical Drag the _onRefreshing function is called, where it updates the Text widget after a delay of 2 seconds.
I want to include a Loading indicator while the _onRefreshing function is running.
How do I implement this task in Flutter?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
dynamic balanceAvailable = 0;
void _onRefreshing(DragEndDetails details) async {
await Future.delayed(const Duration(seconds: 2));
if (details.velocity.pixelsPerSecond.dy > 0) {
setState(() {
balanceAvailable = 1000;
});
print('newbalance : $balanceAvailable');
print(details.velocity.pixelsPerSecond.dy);
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GestureDetector(
onVerticalDragEnd: _onRefreshing,
child: Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {},
child: Text("Button 1"),
),
SizedBox(height: 100.0),
Text('$balanceAvailable'),
],
),
),
),
),
);
}
}
You can return a CircularProgressIndicator inside a showdialog in your _onRefreshing method.
After the 2 seconds delay, you can remove it with Navigator.pop();
Maybe like this:
void _onRefreshing(DragEndDetails details) async {
showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: SizedBox(
height: MediaQuery.of(context).size.height/4,
width: MediaQuery.of(context).size.width/2,
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
),
),
);
});
await Future.delayed(const Duration(seconds: 2));
if (details.velocity.pixelsPerSecond.dy > 0) {
setState(() {
balanceAvailable = 1000;
});
print('newbalance : $balanceAvailable');
print(details.velocity.pixelsPerSecond.dy);
}
Navigator.pop(context);
}
Say I have two pages :-
Tester1.dart
import 'package:flutter/material.dart';
import 'package:gelijk_spel/Testers2.dart';
class Testers1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: IconButton(
icon: Hero(
tag: 'elderimg',
child: Image.asset(
'assets/Images/elder.png', width: 100, height: 100,),
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(
builder: (context) => Testers2()
)
);
}
),
),
),
);
}
}
and Tester2.dart
import 'package:flutter/material.dart';
class Testers2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Screen2'),
),
body: Column(
children: <Widget>[
Text('Placeholder0'),
Hero(
tag: 'elderimg',
child: Image.asset('assets/Images/elder.png',width: 100, height: 100,)
),
Text('Placeholder1'),
],
),
),
);
}
}
I want to be able to transition from Tester1 to Tester2, but instead of having to click on the screen or any events, just sequentially, after some time. How can I achieve this?
One possible approach is to use Timer and a StatefulWidget so you can set up a timer with a trigger that will run your Navigation code as soon as the timer runs out and triggers.
This is the code example:
class Testers1 extends StatefulWidget {
#override
_Testers1State createState() => _Testers1State();
}
class _Testers1State extends State<Testers1> {
Widget build(BuildContext context) {
return Scaffold(
body: Container()
);
}
#override
void initState() {
super.initState();
Timer(Duration(seconds: 10), () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Testers2()));
});
}
}
class Testers2 extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen2'),
),
body: Column(
children: <Widget>[
Text('Placeholder0'),
Text('Placeholder1'),
],
),
);
}
}
NOTE: Timer is coming from the 'dart:async'
Yes, you have to use Future.delayed() on init() function in first page
Like this(Add this to First page):
Future<void> initState() {
super.initState();
//replace 1000 with your time required
Future.delayed(Duration(milliseconds: 1000), () {
Navigator.push(currentContext,
MaterialPageRoute(builder: (context) => Testers2()));
},
});
}
main.dart----
import 'package:flutter/material.dart';
import 'package:flutter_app/splashscreen.dart';
import 'package:flutter_app/homepage.dart';
import 'package:flutter_app/constants.dart';
void main() => runApp(MaterialApp(
title: 'GridView Demo',
home: SplashScreen(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.red,
accentColor: Color(0xFF761322),
),
routes: <String, WidgetBuilder>{
SPLASH_SCREEN: (BuildContext context) => SplashScreen(),
HOME_SCREEN: (BuildContext context) => HomeScreen(),
//GRID_ITEM_DETAILS_SCREEN: (BuildContext context) => GridItemDetails(),
},
));
slashscreen.dart------
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/constants.dart';
class SplashScreen extends StatefulWidget {
#override
SplashScreenState createState() => new SplashScreenState();
}
class SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
var _visible = true;
AnimationController animationController;
Animation<double> animation;
startTime() async {
var _duration = new Duration(seconds: 3);
return new Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.of(context).pushReplacementNamed(HOME_SCREEN);
}
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 2),
);
animation =
new CurvedAnimation(parent: animationController, curve: Curves.easeOut);
animation.addListener(() => this.setState(() {}));
animationController.forward();
setState(() {
_visible = !_visible;
});
startTime();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
new Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 30.0),
child: new Image.asset(
'assets/r1.png',
height: 25.0,
fit: BoxFit.scaleDown,
),
)
],
),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Image.asset(
'assets/r2.png',
width: animation.value * 250,
height: animation.value * 250,
),
],
),
],
),
);
}
}
homepage.dart--------
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Table Widget")),
body: Center(child:Text('jai sri ram ')
)
);
}
}
constants.dart-----
String SPLASH_SCREEN='SPLASH_SCREEN';
String HOME_SCREEN='HOME_SCREEN';
1.Error undefined name 'SPLASH_SCREEN'
2.Error undefined name 'HOME_SCREEN'
3.How can I solve this error?
I don't know why these undefined name errors appear in the screen.I don't know how to solve these errors.
How can I resolve undefined name SPLASH_SCREEN & HOME_SCREEN error ?
Please help me..Thank you
I tried your code and it works fine.
You could try these things:
Run flutter clean in your project directory
Restart / reinstall the app instead of using hot-reload
I see that you don't have initialRoute specified in the MaterialApp. Something like this -
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
Would that solve your problem ? This does not solve the undefined problem btw. The code does look ok (I guess)