flutter 如何解决共享首选项未初始化错误:扑动

tzdcorbm  于 2022-11-25  发布在  Flutter
关注(0)|答案(1)|浏览(226)

方案:我有一个包含ListView的页面,该页面显示了使用REST API从数据库中提取的若干项的列表。我正在initState()方法中加载数据。为了加载数据,我还需要一些存储在共享首选项中的数据。我在加载数据和呈现UI之前获取共享首选项的示例。UI会根据存储在共享首选项中的AccountType进行更改。
**问题:**当我导航到应用程序中的特定页面时,出现错误-

LateInitializationError: Field '_sharedPreferences@53458703' has not been initialized.
The relevant error-causing widget was: 
  QuizListPage QuizListPage:file:///D:/Github_Work/Assessment%20Portal/assessmentportal/lib/Pages/CategoryTile.dart:27:41
When the exception was thrown, this was the stack: 
#0      _QuizListPageState._sharedPreferences (package:assessmentportal/Pages/QuizListPage.dart)
#1      _QuizListPageState.build (package:assessmentportal/Pages/QuizListPage.dart:72:19)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
#4      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
#5      Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
#6      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
#7      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
#8      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
...     Normal element mounting (275 frames)

我的密码是-

class QuizListPage extends StatefulWidget {
  CategoryModel category;

  QuizListPage({required this.category});

  @override
  State<QuizListPage> createState() => _QuizListPageState();
}

class _QuizListPageState extends State<QuizListPage> {
  late SharedPreferences _sharedPreferences;
  List<QuizModel> quizzes = [];
  late CategoryService _categoryService;
  bool _areQuizzesLoaded = false;
  @override
  void initState() {
    super.initState();

    _initializeData();
  }

  void _initializeData() async {
    _sharedPreferences = await SharedPreferences.getInstance();
    _categoryService = CategoryService();
    setState(() {
      _areQuizzesLoaded = false;
    });
    await _loadCategories();
  }

  Future<void> _loadCategories() async {
    if (_sharedPreferences.getString(ROLE) == ROLE_NORMAL) {
      quizzes = await _categoryService.getAllQuizzesByCategory(
          _sharedPreferences.getString(BEARER_TOKEN) ?? 'null',
          widget.category.categoryId);
    } else {
      quizzes = await _categoryService.getAllQuizzesByAdminAndCategory(
        adminid: _sharedPreferences.getInt(USER_ID) ?? 0,
        categoryid: widget.category.categoryId,
        token: _sharedPreferences.getString(BEARER_TOKEN) ?? 'null',
      );
    }
    setState(() {
      log('Setting loaded to true');
      _areQuizzesLoaded = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height -
        AppBar().preferredSize.height -
        MediaQuery.of(context).padding.top -
        MediaQuery.of(context).padding.bottom;
    final width = MediaQuery.of(context).size.width;
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.category.categoryTitle),
        actions: (_sharedPreferences.getString(ROLE) != ROLE_NORMAL)
            ? [
                Container(
                  margin: const EdgeInsets.only(
                    top: 10,
                    right: 10,
                    left: 5,
                    bottom: 5,
                  ),
                  child: ElevatedButton(
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => AddQuizPage(
                            userid: _sharedPreferences.getInt(USER_ID) ?? 0,
                            categoryid: widget.category.categoryId ?? 0,
                            token: _sharedPreferences.getString(BEARER_TOKEN) ??
                                'null',
                          ),
                        ),
                      );
                    },
                    child: const Text('Add Quiz'),
                  ),
                ),
              ]
            : null,
      ),
      body: Container(
        child:Text('Hello'),
           ),
         );
        }
   }

请帮助我了解为什么会出现此错误(有时不总是出现)以及在显示UI之前加载数据的正确方法是什么(某些UI组件取决于存储在共享首选项中的数据),我想使用共享首选项,就像它在我的代码中使用的方式一样。请帮助!

fae0ux8s

fae0ux8s1#

您可以尝试将其修改为以下代码:

bool _spInitOK = false;

void _initializeData() async {
  _sharedPreferences = await SharedPreferences.getInstance();
  setState(() {
    _spInitOK = true;
  });
  ...
}

actions: !_spInitOK
    ? null
    : (_sharedPreferences.getString(ROLE) != ROLE_NORMAL)
        ? [...

以下是我的理解:
第一次

相关问题