0

首先,我像这样初始化了我的相机控制器(相机:^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("");
        }
      ),
    );
  }
}

但现在我想ResolutionPreset从 SharedPreferences ( shared_preferences : ^2.0.13) 动态加载。
有什么好方法可以做到这一点?

像这样尝试时失败了(添加一些变量和更改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.

4

1 回答 1

1

initState不能是async方法,从中获取值SharedPreferencesasync函数。你不能使用await(或then) in initState,我的意思是你可以使用但代码执行不会等待这个完成。所以这里发生的情况是,您的build方法将在未来从SharedPreferences完成中获取值之前运行。而且我认为你_initializeControllerFuture的标记为late,所以当你build尝试使用它时,它仍然是null,这会给你这个错误。

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

于 2022-02-09T21:06:37.227 回答