如何使用 SharedPreferences 初始化 CameraController?

How to initialize CameraController with SharedPreferences?

首先,我像这样初始化了我的相机控制器 (camera: ^0.9.4+11),它可以工作:

class TakePictureScreen extends StatefulWidget {
  final CameraDescription camera;

  const TakePictureScreen({required Key key, required this.camera}) 
    : super(key: key);

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

class TakePictureScreenState extends State<TakePictureScreen> {
  late CameraController _controller;
  late Future<void> _initializeControllerFuture;

  @override
  void initState() {
    super.initState();
    _controller = CameraController(
      widget.camera,
      ResolutionPreset.max, // TODO: this should come from SharedPreferences
    );
    _initializeControllerFuture = _controller.initialize();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          return (snapshot.connectionState == ConnectionState.done)
            ? CameraPreview(_controller)
            : Text("");
        }
      ),
    );
  }
}

但现在我想从 SharedPreferences (shared_preferences: ^2.0.13) 动态加载 ResolutionPreset
执行此操作的好方法是什么?

我尝试这样做时失败了(添加一些变量并更改 initState 方法):

final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
late Future<int> _resolutionIndex;
List<ResolutionPreset> resolutions = ResolutionPreset.values.toList(growable: false);
static const String sharedPrefResolution = "resolution";

@override
void initState() {
  super.initState();
  _resolutionIndex = _prefs.then((SharedPreferences prefs) {
    int resolutionIndex = prefs.getInt(sharedPrefResolution) ?? (resolutions.length - 1);
    _controller = CameraController(
      widget.camera,
      resolutions[resolutionIndex],
    );
    _initializeControllerFuture = _controller.initialize();
    return resolutionIndex;
  });
}  

出现错误:LateInitializationError: Field '_initializeControllerFuture@19039262' has not been initialized.

initState 不能是 async 方法,从 SharedPreferences 获取值是 async 函数。你不能在initState中使用await(或then),我的意思是你可以使用但是代码执行不会等待它完成。所以这里发生的是你的 build 方法将 运行 早于将来从 SharedPreferences 获取值完成。而且我假设你的 _initializeControllerFuture 被标记为 late,所以当你的 build 尝试使用它时,它仍然是 null,这会让你得到这个错误。

解决此问题的常用方法是使用 FutureBuilder。使用 FutureBuilderSharedPreferences 获取值,在加载时显示进度指示器(它会很快,所以如果您认为可以跳过这部分),然后当您从中获取值时,使用来自 SharedPreferences 的值构建您的小部件,并仅在此之后初始化 CameraController