Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigator.pop #172

Open
sm2017 opened this issue Jan 13, 2021 · 11 comments
Open

Navigator.pop #172

sm2017 opened this issue Jan 13, 2021 · 11 comments

Comments

@sm2017
Copy link

sm2017 commented Jan 13, 2021

I am using flutter bloc in my application, is success response I call Navigator.pop to pop the navigator, and in failure I call Flushbar.show to to toast error message

As you push in navigator I have some problem, When I call Navigator.pop and the previous toast is exists in the page , it popped instead of the current page

I know I can use Navigator.popUntil, But I think it is the problem of flushbar library, Because toast must not be a different route

@SardorbekR
Copy link

@sm2017 Have you found a solution?

@sm2017
Copy link
Author

sm2017 commented Feb 6, 2021

@SardorbekR No
@AndreHaueisen Can you please reply, I think you shouldn't use navigation API to show toast

@cmdrootaccess
Copy link

@sm2017 you can use toast in a provider , that will fix it

@sm2017
Copy link
Author

sm2017 commented Feb 6, 2021

@cmdrootaccess Can you show me a sample code for flushbar

@cmdrootaccess
Copy link

yes i will make an example in the next few hours and show you

@sm2017
Copy link
Author

sm2017 commented Feb 15, 2021

@cmdrootaccess Can you help me?

@cmdrootaccess
Copy link

sorry was busy. let me paste the code here. give me a moment

@cmdrootaccess
Copy link

create provider.dart . paste this

import 'package:flutter/material.dart';
import 'package:testtoast/toast.dart';

class AppProvider extends StatefulWidget {
  final Widget child;

  const AppProvider({Key key, @required this.child}) : super(key: key);

  @override
  AppProviderState createState() {
    return AppProviderState();
  }

  static AppProviderState of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_AppProvider)
    as _AppProvider)
        .data;
  }
}
class AppProviderState extends State<AppProvider> {

  Toast toast = new Toast();

  @override
  Widget build(BuildContext context) {

    return new _AppProvider(
      data: this,
      child: widget.child,
    );
  }
}

class _AppProvider extends InheritedWidget {
  final AppProviderState data;

  _AppProvider({Key key, this.data, Widget child})
      : super(key: key, child: child);

  @override
  bool updateShouldNotify(_AppProvider old) {
    return true;
  }
}

create toast.dart paste this.


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:testtoast/toast_widget.dart';
class Toast {

  void showFlushbar({
    String title,
    @required String message,
    @required BuildContext context,
    Duration duration,
  }) {
    if (context != null) {
      ToastWidget.of(context).showFlushbar(title ?? "No Title",message,context,duration);
    } else {
      print('Context was null, cannot show toast');
    }
  }
}

create toast_widget.dart paste this.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:another_flushbar/flushbar.dart';
class ToastWidget extends StatefulWidget {
  final Widget child;

  ToastWidget({this.child});

  @override
  ToastWidgetState createState() {
    return ToastWidgetState();
  }

  static ToastWidgetState of(BuildContext context) {
    final ToastWidgetState toastState =
    context.rootAncestorStateOfType(const TypeMatcher<ToastWidgetState>());
    return toastState;
  }
}
class ToastWidgetState extends State<ToastWidget> {


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

  @override
  Widget build(BuildContext context) {
    return _ToastInWidget(
      child: widget.child,
    );
  }

  Future showFlushbar(String title,
      String message,
      BuildContext context,
      Duration duration){
    Flushbar(
      title:  title,
      message:  message,
      duration:  duration ?? Duration(seconds: 3),
    )..show(context);
  }

}

class _ToastInWidget extends InheritedWidget {
  _ToastInWidget({Key key, Widget child}) : super(key: key, child: child);

  @override
  bool updateShouldNotify(_ToastInWidget old) {
    return true;
  }
}

Then in your main.dart do this . mind the AppProvider at the root instead of MaterialApp

@override
  Widget build(BuildContext context) {
    return AppProvider(
        child: ToastWidget(
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              // This is the theme of your application.
              //
              // Try running your application with "flutter run". You'll see the
              // application has a blue toolbar. Then, without quitting the app, try
              // changing the primarySwatch below to Colors.green and then invoke
              // "hot reload" (press "r" in the console where you ran "flutter run",
              // or simply save your changes to "hot reload" in a Flutter IDE).
              // Notice that the counter didn't reset back to zero; the application
              // is not restarted.
              primarySwatch: Colors.blue,
            ),
            routes: {
              '/': (BuildContext context) {
                return HomePage();
              }
            },
          ),
        )
    );
  }

then in home page or any other page you want to use the toast just call in the build block

var providerState =  AppProvider.of(context);
var toast = providerState.toast;

toast.showFlushbar(title: "Whats Up",message: "Hello World", context: context);

example

import 'package:flutter/material.dart';
import 'package:testtoast/provider.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>{
  @override
  Widget build(BuildContext context) {
    var providerState =  AppProvider.of(context);
    var toast = providerState.toast;
    return Scaffold(
      appBar: AppBar(title: Text("Hello World")),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello flushbar:',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async{
          toast.showFlushbar(title: "Whats Up",message: "Hello World", context: context);
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

@sm2017
Copy link
Author

sm2017 commented Feb 15, 2021

@cmdrootaccess you are using another_flushbar package,not flushbar
But I will try, thanks

@cdprete
Copy link

cdprete commented Jan 20, 2022

I do have the same issue.
The context is somehow shared, therefore when showing a Flushbar this gets pushed in the (default?) Navigator, causing a successive pop to close the message instead of, in my case, an AlertDialog.

Is there no out of the box solution from the library yet?

For now I'm doing

    // Pop until you reach the dialog
    Navigator.popUntil(
      context,
      ModalRoute.withName(AddPlaylistDialog.routeName),
    );
    // Pop the dialog itself
    Navigator.pop(context);

like also @sm2017 suggested, but it's not nice indeed.

@adminant
Copy link

I have the same problem, my flushbar is hidden if I call .pop() in my app to hide modal windows and so on. I want flushbar to be always on the screen. Is there any solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants