Bloc: [Question] How would you manage animation in the bloc builder?

Created on 22 Nov 2018  Β·  10Comments  Β·  Source: felangel/bloc

Hi all, Thanks for this component. Looks very promising.

I'm struggling with a question. How would you manage animation and controller in the Bloc builder?

Image that on the login example you would have a PageView instead of a stack with the Splash as first page and the Login/Home as second page. When the initialization completes you want to use a page controller to animate from the Splash page to the Home/Login page.

How would you do that?

Thanks,

Alex.

question

Most helpful comment

@felangel @basketball-ico Hello

I want to use Navigator too when AuthenticationState changed.

I solved making this, but I want the review of @felangel 😁

Based on the example that you show here

// main.dart
class AppState extends State<App> {

  final AuthenticationBloc _authenticationBloc = AuthenticationBloc();
  StreamSubscription<AuthenticationState> _authenticationStateSubscription;

  void _navigateToRoute(BuildContext context, Widget route) {
    WidgetsBinding.instance.scheduleFrameCallback(
      (_) {
        // When you AuthenticationState changed, and you have
        // pushed a lot widgets, this pop all.
        // You can change the name '/' for the name
        // of your route that manage the AuthenticationState.
        Navigator.popUntil(context, ModalRoute.withName('/'));

        // Also you can change MaterialPageRoute
        // for your custom implemetation
        MaterialPageRoute newRoute = MaterialPageRoute(
          builder: (BuildContext context) {
            // WillPopScope for prevent to go to the previous
            // route using the back button.
            return WillPopScope(
              onWillPop: () async {
                // In Android remove this activity from the stack
                // and return to the previous activity.
                SystemNavigator.pop();
                return false;
              },
              child: route,
            );
          },
        );
        Navigator.of(context).push(newRoute);
      },
    );


  @override
  void initState() {
    _authenticationStateSubscription = _authenticationBloc.state.listen(
      (state) {
        if (state.isInitializing) {
          _navigateToRoute(context, SplashPage());
        } else if (state.isAuthenticated) {
          _navigateToRoute(context, HomePage());
        } else if (state.isUnauthenticated) {
          _navigateToRoute(context, LoginPage());
        }
      },
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // Widget behind transitions
    return Scaffold();
  }

  @override
  void dispose() {
    _authenticationBloc.dispose();
    _authenticationStateSubscription.cancel();
    super.dispose();
  }
}

All 10 comments

Hi @AlexandreRoba! Thanks for taking the time to use Bloc and for opening up an issue.

Regarding your question, you should be able to update the AppState class in the example to something like:

// main.dart
class AppState extends State<App> {
  final AuthenticationBloc _authenticationBloc = AuthenticationBloc();
  final PageController _pageController = PageController();

  AppState() {
    _authenticationBloc.state.listen((state) {
      if (state.isInitializing) {
        _pageController.animateToPage(
          0, // SplashPage
          curve: Curves.ease,
          duration: Duration(milliseconds: 300),
        );
        return;
      }
      if (state.isAuthenticated) {
        _pageController.animateToPage(
          2, // HomePage
          curve: Curves.ease,
          duration: Duration(milliseconds: 300),
        );
      } else {
        _pageController.animateToPage(
          1, // LoginPage
          curve: Curves.ease,
          duration: Duration(milliseconds: 300),
        );
      }
    });
    _authenticationBloc.onAppStart();
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<AuthenticationBloc>(
      bloc: _authenticationBloc,
      child: MaterialApp(
        home: PageView(
          physics: NeverScrollableScrollPhysics(),
          children: [
            SplashPage(),
            LoginPage(),
            HomePage(),
          ],
          controller: _pageController,
        ),
      ),
    );
  }

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

This way you are updating the current page using the PageController in response to the state changes in the AuthenticationBloc but since you are not changing the widgets you don't need to use BlocBuilder.

Hope that makes sense and let me know if you have any other questions! πŸ‘

@AlexandreRoba closing this for now.
Let me know if you have any questions/comments and I'm happy to reopen it.

Thanks for the clarification. I’ll try this.
On 24 Nov 2018, 22:15 +0100, Felix Angelov notifications@github.com, wrote:

@AlexandreRoba closing this for now.
Let me know if you have any questions/comments and I'm happy to reopen it.
β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@felangel hello,
Do you have others way to animate when AuthenticationBloc change state?
Thanks

@basketball-ico πŸ‘‹
Did you have something in particular that you’re looking to accomplish? At the end of the day it’s all up to you haha πŸ˜„

hello, I'm looking for a way to make them work with Navigator.of..., so that I can create my own PageRouterBuilder and be able to create any transition that I need, but I still can not make it work :(

@basketball-ico can you share a sample app without bloc so that I can see what you’re trying to do and then I can help suggest how to accomplish the same with bloc? Thanks! πŸ‘

@felangel @basketball-ico Hello

I want to use Navigator too when AuthenticationState changed.

I solved making this, but I want the review of @felangel 😁

Based on the example that you show here

// main.dart
class AppState extends State<App> {

  final AuthenticationBloc _authenticationBloc = AuthenticationBloc();
  StreamSubscription<AuthenticationState> _authenticationStateSubscription;

  void _navigateToRoute(BuildContext context, Widget route) {
    WidgetsBinding.instance.scheduleFrameCallback(
      (_) {
        // When you AuthenticationState changed, and you have
        // pushed a lot widgets, this pop all.
        // You can change the name '/' for the name
        // of your route that manage the AuthenticationState.
        Navigator.popUntil(context, ModalRoute.withName('/'));

        // Also you can change MaterialPageRoute
        // for your custom implemetation
        MaterialPageRoute newRoute = MaterialPageRoute(
          builder: (BuildContext context) {
            // WillPopScope for prevent to go to the previous
            // route using the back button.
            return WillPopScope(
              onWillPop: () async {
                // In Android remove this activity from the stack
                // and return to the previous activity.
                SystemNavigator.pop();
                return false;
              },
              child: route,
            );
          },
        );
        Navigator.of(context).push(newRoute);
      },
    );


  @override
  void initState() {
    _authenticationStateSubscription = _authenticationBloc.state.listen(
      (state) {
        if (state.isInitializing) {
          _navigateToRoute(context, SplashPage());
        } else if (state.isAuthenticated) {
          _navigateToRoute(context, HomePage());
        } else if (state.isUnauthenticated) {
          _navigateToRoute(context, LoginPage());
        }
      },
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // Widget behind transitions
    return Scaffold();
  }

  @override
  void dispose() {
    _authenticationBloc.dispose();
    _authenticationStateSubscription.cancel();
    super.dispose();
  }
}

@GiancarloCode I think your implementation looks really good πŸ‘
It's very simple, easy to read, and easy to test πŸ’―πŸŽ‰

@basketball-ico does @GiancarloCode's implementation answer your question?

@felangel @GiancarloCode
Thanks, that works perfect, that is that I was searching. πŸŽ‰πŸŽ‰πŸŽ‰

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clicksocial picture clicksocial  Β·  3Comments

rsnider19 picture rsnider19  Β·  3Comments

nerder picture nerder  Β·  3Comments

krusek picture krusek  Β·  3Comments

timtraversy picture timtraversy  Β·  3Comments