Flutter Future<bool>, RX<bool>, and regular bool混淆以及如何从另一个获取一个的值

Flutter Future<bool>, RX<bool>, and regular bool confusion and how to get the value of one from the other

我是 Flutter 的新手,刚刚了解了 GetX,所以我试图尽可能地将它整合到我的应用程序中。在这个例子中,我试图获得存储权限,并让小部件反应,如果它被授予或不被授予更改文本和颜色等。

我调用存储权限的函数返回了一个像这样的未来...

  Future<bool> requestStoragePermissions() async {
    final storagePermissionStatus = await Permission.storage.request();

    if (storagePermissionStatus == PermissionStatus.granted) {
      debugPrint('Notification Permission Granted');
      return true;
    } else if (storagePermissionStatus == PermissionStatus.denied) {
      debugPrint('Notification Permission Denied');
    } else if (storagePermissionStatus == PermissionStatus.permanentlyDenied) {
      debugPrint('Notification Permission Permanently Denied');
      await openAppSettings();
    }

    if (storagePermissionStatus == PermissionStatus.granted) {
      return true;
    } else {
      return false;
    }
  }

在我的权限屏幕中,我有一种方法可以根据发送到 class...

的参数来选择我想要的权限
Future<bool> checkPermissions() async {
  print('Permission Type: ' + permissionType.toString());
  bool statusGranted = false;
  if (permissionType == Permission.camera) {
    statusGranted = await _permissionController.requestCameraPermission();
  } else if (permissionType == Permission.location) {
    statusGranted = await _permissionController.requestLocationPermissions();
  } else if (permissionType == Permission.notification) {
    statusGranted = await _permissionController.requestNotificationPermissions();
  } else if (permissionType == Permission.storage) {
    statusGranted = await _permissionController.requestStoragePermissions();
  }
  return Future<bool>.value(statusGranted);
}

我将 return 更改为 future 但我在玩它时确实将其作为 statusGranted。如何在条件语句中使用值 Future?我不断收到无法将 Future 与 bool 进行比较的错误。

这里我试图根据是否授予权限有条件地将按钮图标设置为不同。

SizedBox(
  width: 100,
  child: _permissionGranted.value == false
      ? const Icon(
          Icons.no_photography,
          size: 40,
          color: Colors.red,
        )
      : const Icon(
          Icons.camera_alt,
          size: 40,
          color: Colors.green,
        ),
),

我把 _permissionsGranted.value 放在那里是因为一开始我在那里有 checkPermission() == falsa 。现在我只是在尝试一些随机的事情,并且离我需要的地方更远,这就是我来这里寻求帮助的原因。

如标题所述,在旁注中。现在我们有 3 个不同的 Bools 可以使用。有没有正确的方法可以互换使用它们?

编辑:

每次按下此按钮时都会检查 checkPermission...

Obx(
    () => ElevatedButton(
      child: _permissionGranted.value == false ? const Text('Click Me') : const Text('Done'),
      onPressed: _permissionGranted.value == false
          ? () async {
              await checkPermissions();
            }
          : null,

我基本上是在我的屏幕小部件中创建这个按钮,并决定将它提取到它自己的小部件中,这样我就可以使用更多相同的按钮来检查同一页面上的不同权限检查。

在我用头撞墙试图解决这个问题几个小时后,我遇到了一个论坛,它告诉我我可以在 onPressed 中使用异步:属性。因此,我在我的 permissionsController 中创建了一个 RX,以针对我所做的每个权限检查进行更改,并将其用作更改小部件行为的三元条件。所以我不得不添加这个方法,它在方法成功完成时接受布尔值

void permissionGranted() {
  if (permissionType == Permission.camera) {
    _permissionGranted.value = _permissionController.mediaGranted.value;
  } else if (permissionType == Permission.location) {
    _permissionGranted.value = _permissionController.locationGranted.value;
  } else if (permissionType == Permission.notification) {
    _permissionGranted.value = _permissionController.notificationsGranted.value;
  } else if (permissionType == Permission.storage) {
    _permissionGranted.value = _permissionController.storageGranted.value;
  }
}

正如我在 post 编辑中展示的那样,我现在在三元语句中使用了 checkPermission 方法,而不是尝试使用 is AS 三元语句。

Obx(
  () => ElevatedButton(
    child: _permissionGranted.value == false ? const Text('Click Me') : const Text('Done'),
    onPressed: _permissionGranted.value == false
        ? () async {
            await checkPermissions();
          }
        : null,

这是我更新的 checkPermission 方法...

bool statusGranted = false;
Future<bool> checkPermissions() async {
  //print('Permission Type: ' + permissionType.toString());
  if (permissionType == Permission.camera) {
    statusGranted = await _permissionController.requestCameraPermission();
    permissionGranted();
  } else if (permissionType == Permission.location) {
    statusGranted = await _permissionController.requestLocationPermissions();
    permissionGranted();
  } else if (permissionType == Permission.notification) {
    statusGranted = await _permissionController.requestNotificationPermissions();
    permissionGranted();
  } else if (permissionType == Permission.storage) {
    statusGranted = await _permissionController.requestStoragePermissions();
    permissionGranted();
  }
  return statusGranted;
}

仍然对混合使用 3 种不同布尔类型的互换性感到非常困惑。 Future、RX 和常规 bool。

如果您对 Futures 感到困惑,那么我建议您继续阅读 async programming in Dart ,因为它是一个需要理解的重要概念。这是一个 Future,因为它必须 await 在设置 bool 的值之前检查权限的进程。

任何类型的 Future 仅意味着该值不会被 return 编辑,直到发生其他进程,即...从某些外部 API 请求数据或检查权限等...

RxBool vs boolboolean 与常规 boolean 的流。使用 Obx 需要在其中有一个流,因为它的工作是侦听流并在流的值更新时重建。正如您所知,要访问实际的原语 bool,您可以使用 .value.

在你的情况下,你的屏幕上有一堆逻辑,它们都可以存在于 GetX class 中并清理你的 UI 代码。 UI 应该关心的是 controller.permissionGranted

的值

您的 Future<bool> checkPermissions() 不需要 return 一个 bool 它只需要更新 permissionGranted 的值。所有其他函数都可以是私有的,因为 UI 不需要知道 checkPermissions() 做什么。

// all of this lives in the GetX class
  Future<void> checkPermissions() async {
    if (permissionType == Permission.camera) {
      permissionGranted.value = await _requestCameraPermission();
    } else if (permissionType == Permission.location) {
      permissionGranted.value = await _requestLocationPermissions();
    } // continue with others...
  }

这是一个示例,说明在 UI

中的样子
class TestPage extends StatelessWidget {
  final controller = Get.find<PermissionController>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Obx(
          () => ElevatedButton(
              child: !controller.permissionGranted
                      .value // note the ! saves from having to write "== false"
                  ? const Text('Click Me')
                  : const Text('Done'),
              onPressed: !controller.permissionGranted.value
                  ? () async {
                      await controller.checkPermissions();
                    }
                  : null),
        ),
      ),
    );
  }
}