Skip to content
This repository was archived by the owner on Nov 24, 2020. It is now read-only.

ProgressDialog won't show again when coming back from a previous screen. #54

Closed
rhyscoronado opened this issue Apr 22, 2020 · 17 comments
Closed
Assignees

Comments

@rhyscoronado
Copy link

Describe the bug
Screen with ProgressDialog loading a content, after the content loads, the ProgressDialog is hidden and it moves to the next screen, when you pop back to that screen, and when you try to show the ProgressDialog again, it doesn't show.

Expected behavior
Should show without error

Log
flutter: Exception while showing the dialog [VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: type 'FlutterError' is not a subtype of type 'String' #0 ProgressDialog.show (package:progress_dialog/progress_dialog.dart:160:18) #1 _ProjectMapPageState.routeTraffic (package:signtracker/feature/project/maps/project_map_page.dart:469:8) #2 _ProjectMapPageState.build.<anonymous closure> (package:signtracker/feature/project/maps/project_map_page.dart:316:46) #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14) #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36) #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11) #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5) #8 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7) #9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9) #10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12) #11 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9) #12 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8) #13 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18) #14 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7) #15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) #16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) #17 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) #18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) #19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) #20 _rootRunUnary (dart:async/zone.dart:1138:13) #21 _CustomZone.runUnary (dart:async/zone.dart:1031:19) #22 _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7) #23 _invoke1 (dart:ui/hooks.dart:273:10) #24 _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)

Smartphone (please complete the following information):

Device: iPhone5s
OS: iOS.12
flutter
Flutter 1.12.13+hotfix.9 • channel stable • [email protected]:flutter/flutter.git
Framework • revision f139b11009 (3 weeks ago) • 2020-03-30 13:57:30 -0700
Engine • revision af51afceb8
Tools • Dart 2.7.2

@xsahil03x
Copy link
Contributor

@rhyscoronado please share some code through which we can replicate the issue.

@fayaz07
Copy link
Owner

fayaz07 commented Apr 22, 2020

Also @rhyscoronado @xsahil03x , we have the dialog configured as to use the context of the current screen and display the dialog, if the current screen has to pop, first the dialog will get popped from the stack and then the screen.

@rhyscoronado are you trying just to push or pushReplacement ?

@rhyscoronado
Copy link
Author

rhyscoronado commented Apr 23, 2020

@xsahil03x @fayaz07

`

  void routeTraffic() async {
    pr.style(message: 'Loading accurate location...');
    await pr.show();
    final currentLocation = await Location().getLocation();
    await pr.hide();
    final result = await Navigator.pushNamed(
      context,
      TrafficPage.route,
      arguments: TrafficPageArgs(
        project.id,
        LatLng(currentLocation.latitude, currentLocation.longitude),
        widget.project,
      ),
    );
if (result != null) {
  //add sign here
  method = 'add-sign';
  print('METHOD:  $method');
  bloc.loadProjectSigns(project.id);
}

}`

That's the part of the project code being executed that triggers the error log I posted earlier.

So after going to the Traffic Page Route, I just pop that Traffic Page with a result.
Then when that code is called again, the dialog won't popup.

@prashant3285
Copy link

prashant3285 commented May 8, 2020

I am having same issue.

From my drawer I navigate to Profile page
Progress Dialog works
I use popAndPushNamed for this navigation

When I pop the Profile page using back nav button (pop)
And retry to navigate to Profile page.
Progress bar doesn't show with error.

I Just modified the lib files to show error as String, hence my error looks different.

I/flutter ( 6760): Exception while showing the dialog
I/flutter ( 6760): Looking up a deactivated widget's ancestor is unsafe.
I/flutter ( 6760): At this point the state of the widget's element tree is no longer stable.
I/flutter ( 6760): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

@fayaz07
Copy link
Owner

fayaz07 commented May 9, 2020

When you pop, as Dialog in Flutter uses the root Navigator it pops the dialog first, then the screen, so there is no issue about it.

You can have something like, pushNamed or push instead of pushReplacement, if you need the dialog in the current screen to be alive

@fayaz07 fayaz07 closed this as completed May 9, 2020
@rhyscoronado
Copy link
Author

I don't think the problem was resolved on my situation compared to the latter who commented 23 hours ago.

If you can, what's wrong with the code I posted?

@fayaz07
Copy link
Owner

fayaz07 commented May 9, 2020

void routeTraffic() async {
    pr.style(message: 'Loading accurate location...');
    await pr.show();
    final currentLocation = await Location().getLocation();
   // here you are hiding the dialog
    await pr.hide();
    final result = await Navigator.pushNamed(
      context,
      TrafficPage.route,
      arguments: TrafficPageArgs(
        project.id,
        LatLng(currentLocation.latitude, currentLocation.longitude),
        widget.project,
      ),
    );

after hiding the dialog, how can you expect it to show?

@prashant3285
Copy link

void routeTraffic() async {
    pr.style(message: 'Loading accurate location...');
    await pr.show();
    final currentLocation = await Location().getLocation();
   // here you are hiding the dialog
    await pr.hide();
    final result = await Navigator.pushNamed(
      context,
      TrafficPage.route,
      arguments: TrafficPageArgs(
        project.id,
        LatLng(currentLocation.latitude, currentLocation.longitude),
        widget.project,
      ),
    );

after hiding the dialog, how can you expect it to show?

But, once the routeTraffic() is recalled the dialog should show.
That is not happening

@fayaz07 fayaz07 reopened this May 9, 2020
@fayaz07
Copy link
Owner

fayaz07 commented May 9, 2020

can you please share the complete code to reproduce?

@fayaz07 fayaz07 added the waiting for response waiting for the customer to respond with the updated code/comment label May 9, 2020
@fayaz07 fayaz07 self-assigned this May 9, 2020
@prashant3285
Copy link

prashant3285 commented May 9, 2020

Ok So I was able to find the issue causing scenario.
This should be helpful

I tried to replicate the issue with a simple code.
Unfortunately (for me) , everything seems to work fine.

So I use drawer from home page to navigate to profile page.
I use a Progress Dialog on the drawer item before it navigates to profile page.
I used popAndPushNamed.
No errors. All work fine.

But when I took the test code more closer to my actual code.
The Error starts to appear (thank god).

Here is the learning
If your Home Page, Drawer and Landing page all have a Progress Dialog then the Progress dialog gives error on 2nd attempt and then onward.

My Code
main.dart

import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';

import 'drawer.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Widget build(context) {
    return MaterialApp(
      title: 'PDTest',
      initialRoute: '/home', 
      routes: {
        '/home': (context) {
          return HomePage();
        },
        '/profile': (conetxt) {
          return ProfilePage();
        },
      },
    );
  }
}

class HomePage extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    ProgressDialog _pr = ProgressDialog(
      context,
      type: ProgressDialogType.Normal,
      isDismissible: false,
    );
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      drawer: drawerMenu(context),
      body: Center(
        child: Text('Home Page'),
      ),
    );
  }
}

class ProfilePage extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    ProgressDialog _pr = ProgressDialog(
      context,
      type: ProgressDialogType.Normal,
      isDismissible: false,
    );
    return Scaffold(
      appBar: AppBar(
        title: Text('Profile Page'),
      ),
      body: Center(
        child: Text('Profile Page'),
      ),
    );
  }
}

drawer.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';

Widget drawerMenu(BuildContext context) {
  ProgressDialog _pr = ProgressDialog(
    context,
    type: ProgressDialogType.Normal,
    isDismissible: false,
  );
  return Drawer(
    child: ListView(
      children: <Widget>[
        DrawerHeader(child: null),
        ListTile(
          title: Text('Profile Page'),
          onTap: () async {
            await _pr.show();
            Timer(Duration(seconds: 3), () async {
              if (_pr.isShowing()) await _pr.hide();
              Navigator.popAndPushNamed(context, '/profile');
            });
          },
        ),
      ],
    ),
  );
}

This is the complete code, you can run and test it.

@fayaz07 fayaz07 removed the waiting for response waiting for the customer to respond with the updated code/comment label May 9, 2020
@fayaz07
Copy link
Owner

fayaz07 commented May 9, 2020

Checkout this commit. This will be a temporary solution.

Behaviour
When you create an instance, the progressDialog will make use of the latest context, that's with it. So if you need to use the old one's, you might need to re-initialize the dialog.

@prashant3285
Copy link

prashant3285 commented May 10, 2020

Checkout this commit. This will be a temporary solution.

Behaviour
When you create an instance, the progressDialog will make use of the latest context, that's with it. So if you need to use the old one's, you might need to re-initialize the dialog.

Temporary solution is having same error behavior.

So I put the initialization just above the usage.
That way _pr is initialized every time on tap. Will this cause any issue?

@fayaz07
Copy link
Owner

fayaz07 commented May 10, 2020

I have run the issue_57.dart file and it's working fine

@fayaz07 fayaz07 closed this as completed May 10, 2020
@rhyscoronado
Copy link
Author

rhyscoronado commented May 20, 2020

Isn't it a bad thing to put the initialization of the ProgressDialog inside the

@override
  Widget build(BuildContext context) {
}

Specially for StatefulWidgets, since they are rebuilt every time, what are we going to do with that?

@fayaz07 @xsahil03x

@rhyscoronado
Copy link
Author

Care to look back into this @fayaz07 @xsahil03x @prashant3285

@fayaz07
Copy link
Owner

fayaz07 commented May 29, 2020

well I have added in the latest docs to make it final

@rhyscoronado
Copy link
Author

But doesn't that render the progress dialog customizable should you want to update the message or other properties?

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

No branches or pull requests

4 participants