Home > Mobile >  How distinguish inner context?
How distinguish inner context?

Time:10-08

I wrote the code like data: (data){Navigator.of(context).pop();},//here to pop showDialog but actually other Navigator.of(context) was popped and figured out that I should distinguish inner context in builder: (context) { //here2 from outer context but could not reach how to do that. Would somebody please give me some advise to solve this ?

    final authC = ref.watch(authFutureProvider);
    authC.when(
      data: (data){Navigator.of(context).pop();},//here
      error: (error, stackTrace) {},
        loading: () {
        final loading = 
        WidgetsBinding.instance.addPostFrameCallback((_) {
            showDialog(
            barrierDismissible: false,
            context: context,
            builder: (context) { //here2
              return const Center(
                child: CircularProgressIndicator(),
              );
            }
        );
        });
      },
    );

CodePudding user response:

I strongly not recommend WidgetsBinding.instance.addPostFrameCallback to show loading because it takes time to render, so your app will load a loading function. It will make End-user can do multiple clicks on the button because the loading has not rendered yet.

this package is verylight and easy to use, the dismiss and show even different from regular widget, so you will not accidentally close your screen because wrong logic or back-end handler failure.

class LoadingExample {

showLoadingExample(){
EasyLoading.instance
  ..displayDuration = const Duration(milliseconds: 2000)
  ..indicatorType = EasyLoadingIndicatorType.fadingCircle
  ..loadingStyle = EasyLoadingStyle.dark
  ..indicatorSize = 45.0
  ..radius = 10.0
  ..progressColor = Colors.yellow
  ..backgroundColor = Colors.green
  ..indicatorColor = Colors.yellow
  ..textColor = Colors.yellow
  ..maskColor = Colors.blue.withOpacity(0.5)
  ..userInteractions = true
  ..dismissOnTap = false
  ..customAnimation = CustomAnimation();
}

dismissExampleLoading(){
EasyLoading.dismiss();
}
}

to call it simply do: *I recommend OOP so you can modify it in 1 place when you need.

LoadingExample().showLoadingExample();
or 
LoadingExample().dismissExampleLoading();

even you accidentally call show or dissmiss multiple time, the loading will not stack, and it will just recall or reset the animation. So your app will not crash

Flutter_easyloading

CodePudding user response:

Well, you can easily define different BuildContexts by giving them different names, like this:

  @override
  Widget build(BuildContext parentContext) {
    final authC = ref.watch(authFutureProvider);
    authC.when(
      data: (data){Navigator.of(parentContext).pop();},//here
      error: (error, stackTrace) {},
      loading: () {
        final loading =
        WidgetsBinding.instance.addPostFrameCallback((_) {
          showDialog(
              barrierDismissible: false,
              context: parentContext,
              builder: (context) { //here2
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
          );
        });
      },
    );
    return Widget();
}

However, that won't change the fact that the context I've named "parentContext" is the parent context! This is the context sent TO the Dialog, not the context of the Dialog itself.

If you want to pop whichever context is on top at the moment, you can define a GlobalKey variable like this:

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

class GlobalVariable {
  static final GlobalKey<NavigatorState> navState = GlobalKey<NavigatorState>();
}

Then, you can pop the current context like this, from anywhere:

import 'global.dart';

void func(){
  Navigator.pop(GlobalVariable.navState.currentContext!);
}

That should pop the Dialog IF the Dialog is currently on top...

But of course, if some other BuildContext is on top, then that will be popped, instead.

  • Related