4

I'm trying to make the logo fade in, and then fade out, in a Splash Screen. After this, it would be redirected to another page. I could not find a way to make it do both in and out fades. I'd like not to use any dependency to accomplish this as well. I've tried to change the future to accept a parameter, but it didn't work. Any

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:shopperbr1/t.dart';

class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  bool animate = false;

  @override
  void initState() {
    super.initState();
    fadeInAnimation();
  }

  Future fadeInAnimation() async {
    await Future.delayed(const Duration(seconds: 2));

    setState(() {
      animate = true;
    });

    await Future.delayed(const Duration(seconds: 2));

    Get.offAll(() => const t());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AnimatedOpacity(
              duration: const Duration(seconds: 1),
              opacity: animate ? 1 : 0,
              child: const Image(
                image: AssetImage('assets/images/transparent_logo.png'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Any help would be really appreciated.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Rod Rodrigues
  • 53
  • 1
  • 9

4 Answers4

1

Can you try something like this?

import 'package:flutter/material.dart';

class FadeTransitionDemo extends StatefulWidget {
  _FadeTransitionDemoState createState() => _FadeTransitionDemoState();
}

class _FadeTransitionDemoState extends State<FadeTransitionDemo>
    with TickerProviderStateMixin {

  AnimationController _controller;
  Animation<double> _animation;

  initState() {
    super.initState();

    _controller = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,

    )..repeat(reverse:true);
    _animation = CurvedAnimation(
        parent: _controller,
        curve: Curves.easeIn
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xffffffff),
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text( 'FadeTransition Demo',),
      ),
      body: Center(
        child: FadeTransition(
          opacity: _animation,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Hello world",style: TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold),
              ),
              Image.asset("assets/devs.jpg"),
            ],
          ),
        ),
      ),
    );
   }
}

Hope that helps !

inkredusk
  • 919
  • 4
  • 16
1

Here's my take on it. I'm using package:flutter_animate, which I highly recommend. By passing the completer down into the splash screen, I know when the animation is complete. In the meanwhile, anything that is await'ed above awaiting done.future will be run in parallel with the animation. Make sure the end of the animation is worthy of a hold, as anything taking longer will delay the transition to the real main app while holding on the final frame of the animation.

import 'dart:async';
    
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';

Future<void> main() async {
  final done = Completer<void>();
  runApp(BigRedOne(done: done));
  // other async stuff goes here
  await done.future;
  runApp(
    const MyApp(),
  );
}

class BigRedOne extends StatelessWidget {
  const BigRedOne({
    required this.done,
    super.key,
  });
  final Completer<void> done;

  @override
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Material(
        child: SizedBox.expand(
          child: ColoredBox(
            color: Colors.red,
            child: FittedBox(
              child: const Text('1')
                  .animate(onComplete: (_) => done.complete())
                  .fadeIn(duration: 2000.ms)
                  .then()
                  .fadeOut(),
            ),
          ),
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Text('Hello World'),
      ),
    );
  }
}
Randal Schwartz
  • 39,428
  • 4
  • 43
  • 70
1

with a little help of Flutter documentation https://api.flutter.dev/flutter/widgets/FadeTransition-class.html https://docs.flutter.dev/development/ui/animations/tutorial After complete the widget animation run a function in Flutter and @inkredusk I was able to get what I was looking for. Thanks

class SplashScreen extends StatefulWidget {
_SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  
late AnimationController _controller;
late Animation<double> _animation;

@override
void initState() {
super.initState();

_controller = AnimationController(
  duration: const Duration(seconds: 5),
  vsync: this,
);

//_animation = CurvedAnimation(parent: _controller, curve: Curves.easeIn);

_animation = Tween<double>(begin: 0, end: 1).animate(_controller)
  ..addStatusListener((status) {
    if (status == AnimationStatus.completed) {
      _controller.reverse().then((value) => Get.offAll(() => const t()));
    }
  })
  ..addStatusListener((status) => print('$status'));

_controller.forward();
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
  backgroundColor: Colors.white,
  body: Center(
    child: FadeTransition(
      opacity: _animation,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset('assets/images/transparent_logo.png'),
        ],
      ),
    ),
  ),
);
}
}
Rod Rodrigues
  • 53
  • 1
  • 9
0

I tried to keep it as simple as possible.

class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

 @override
State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
  with SingleTickerProviderStateMixin {
 late AnimationController _controller;
 late Animation<double> _animation;

 @override
 void initState() {
  super.initState();

_controller = AnimationController(
  duration: const Duration(seconds: 1),
  vsync: this,
);

//_animation = CurvedAnimation(parent: _controller, curve: Curves.easeIn);

_animation = Tween<double>(begin: 0, end: 1).animate(_controller)
  ..addStatusListener(
    (status) {
      if (status == AnimationStatus.completed) {
        _controller.reverse().then(
              (value) => Navigator.pushAndRemoveUntil(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const AuthCheck(),
                  ),
                  (route) => false),
            );
        }
      },
    )
    ..addStatusListener(
      (status) => print('$status'),
    );

  _controller.forward();
}

@override
void dispose() {
  _controller.dispose();
  super.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    body: Center(
      child: FadeTransition(
        opacity: _animation,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('assets/images/transparent_logo.png'),
          ],
        ),
      ),
    ),
  );
}
}
Rod Rodrigues
  • 53
  • 1
  • 9