Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
114 views
in Technique[技术] by (71.8m points)

android - Undismissible dialog in Flutter

What I want to achieve is to make dialog that's impossible to dismiss by clicking back button in android.

I know about barrierDismissible property of showDialog method, but it only does what the name suggests. With it set to false and clicking on back button the dialog still disappears.

I also tried to wrap my code in WillPopScope to intercept back button click, but onWillPop is never called if the dialog is shown. Maybe I messed up with context or something, or there's another way to achieve this behavior? Any help is appreciated.

I've modified the default counter app a bit to show at which stage my research is currently

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _isLocationWarningActive = false;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        // this is never called if the dialog is shown
        if (_isLocationWarningActive) return true;
        return false;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: LocationChecker(
            isLocationWarningActive: _isLocationWarningActive,
            setIsLocationWarningActive: (value) {
              setState(() {
                _isLocationWarningActive = value;
              });
            },
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ), // This trailing comma makes auto-formatting nicer for build methods.
      ),
    );
  }
}

class LocationChecker extends StatefulWidget {
  final bool isLocationWarningActive;
  final Function(bool) setIsLocationWarningActive;
  final Widget child;

  const LocationChecker({Key key, this.setIsLocationWarningActive, this.isLocationWarningActive, this.child}) : super(key: key);
  
  @override
  _LocationCheckerState createState() => _LocationCheckerState();
}

class _LocationCheckerState extends State<LocationChecker> with WidgetsBindingObserver {
  
  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }
  
  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
  
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    print("state: $state");
    if (state == AppLifecycleState.resumed && !_isCheckingLocation) {
      _showLocationSettingsAlertIfNeeded();
    }
  }

  bool _isCheckingLocation = false;
  Future _showLocationSettingsAlertIfNeeded() async {
    if (!mounted) return;
    _isCheckingLocation = true;
  
    if (await checkLocationPermission) {
      if (widget.isLocationWarningActive) {
        widget.setIsLocationWarningActive(false);
        _isCheckingLocation = false;
        Navigator.of(context).pop(true);
      }
    } else if (!widget.isLocationWarningActive) {
      print("should show notification");
      widget.setIsLocationWarningActive(true);
      await showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) =>
            OneActionDialog(
              title: "Location Settings",
              child: Text("Click OK to goto settings"),
              btnTitle: "OK",
              action: () {
                widget.setIsLocationWarningActive(false);
                _isCheckingLocation = false;
                SystemSetting.goto(SettingTarget.LOCATION);
                Navigator.of(context).pop(true);
              },
            ),
      );
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Container(
      child: widget.child,
    );
  }
}

Future<bool> get checkLocationPermission async {
  ServiceStatus serviceStatus = await LocationPermissions().checkServiceStatus();
  if (serviceStatus != ServiceStatus.enabled) return false;
  final access = await LocationPermissions().checkPermissionStatus();
  switch (access) {
    case PermissionStatus.unknown:
    case PermissionStatus.denied:
    case PermissionStatus.restricted:
      final permission = await LocationPermissions().requestPermissions(
        permissionLevel: LocationPermissionLevel.locationAlways,
      );
      if (permission == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
      break;
    case PermissionStatus.granted:
      return true;
      break;
    default:
      return false;
      break;
  }
}
question from:https://stackoverflow.com/questions/65888202/undismissible-dialog-in-flutter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...