Flutter中的提供者在应用的第一次构建时不返回。

huangapple go评论66阅读模式
英文:

Provider in Flutter doesn't return at the first build of App

问题

Flutter中的提供者(Provider)在应用的第一次构建时不会立即返回。在我的应用中,您可以选择应用的主要颜色。例如,当我将其设置为颜色2(int代表颜色)时,我使用Shared Preferences保存它,并在每个页面和小部件中使用提供者。足够简单!但是在应用的第一次构建时,它不会获取颜色。以下是更好理解的图像:

应用程序启动时:

Flutter中的提供者在应用的第一次构建时不返回。

当我使用导航栏时:

Flutter中的提供者在应用的第一次构建时不返回。

希望您能通过这些图像理解问题。有人可以帮忙在应用的第一次构建时立即获取颜色吗?

这是用于切换颜色的提供者:

class ColorProvider with ChangeNotifier {
  int _selectedColor = 0;
  Color _mainColor = Colors.blue;

  ColorProvider() {
    _getColor();
  }

  int get selectedColor => _selectedColor;

  set selectedColor(int index) {
    _selectedColor = index;
    _saveColor();
    notifyListeners();
  }

  Color get mainColor => _mainColor;

  Future<void> _saveColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt('_selectedColorKey', _selectedColor);
  }

  Future<void> _getColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final savedSelectedColor = prefs.getInt('_selectedColorKey');
    if (savedSelectedColor != null) {
      _selectedColor = savedSelectedColor;
    }
  }

  // 这段代码可以在另一个小部件中使用,提供者和prefs仅保存一个int,所以您可以选择(这不太重要)
  _getMainClr(int no) {
    switch (no) {
      case 0:
        _mainColor = blueClr;
        return blueClr;
      case 1:
        _mainColor = tifBlueClr;
        return tifBlueClr;
      case 2:
        _mainColor = yellowClr;
        return yellowClr;
      default:
        _mainColor = blueClr;
        return blueClr;
    }
  }
}

我尝试实现此代码,以便它可以在开始时获取getPrefs,但是上面的color Provider 已经基本上已经实现了这个功能,但是这段代码值得一试。

  @override
  void initState() {
    super.initState();
    getPrefs();
  }

  Future<void> getPrefs() async {
    // 获取int类型的选定颜色
    setState(() {});
  }
英文:

Provider in Flutter doesn't return at the first build of App. In my app you can select the primary color of the app. So when I make it color 2 for example (int represent a color) I save it using Shared Preferences and use it in every page and widget using provider. Easy enough! But at the first build of the app it doesn't fetch the color. Images for beter understanding:

When app is launched:

Flutter中的提供者在应用的第一次构建时不返回。

When I use the NavBar:

Flutter中的提供者在应用的第一次构建时不返回。

Hopefully you can understand the problem with the use of the images. Can anyone help with it fetching the color immediately at the first build of the app.

This is the provider for the switching of the colors:

class ColorProvider with ChangeNotifier {
  int _selectedColor = 0;
  Color _mainColor = Colors.blue;

  ColorProvider() {
    _getColor();
  }

  int get selectedColor =&gt; _selectedColor;

  set selectedColor(int index) {
    _selectedColor = index;
    _saveColor();
    notifyListeners();
  }

  Color get mainColor =&gt; _mainColor;

  Future&lt;void&gt; _saveColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt(&#39;_selectedColorKey&#39;, _selectedColor);
  }

  Future&lt;void&gt; _getColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final savedSelectedColor = prefs.getInt(&#39;_selectedColorKey&#39;);
    if (savedSelectedColor != null) {
      _selectedColor = savedSelectedColor;
    }
  }

  // This code can be used in another widget the provider and prefs only
  // saves an int so with this you can choose (this isn&#39;t too important)
  _getMainClr(int no) {
    switch (no) {
      case 0:
        _mainColor = blueClr;
        return blueClr;
      case 1:
        _mainColor = tifBlueClr;
        return tifBlueClr;
      case 2:
        _mainColor = yellowClr;
        return yellowClr;
      default:
        _mainColor = blueClr;
        return blueClr;
    }
  }
}

I tried to implement this code so that it can fetch the getPrefs at the start but the color Provider above pretty much does this already but this code was worth a try.

  @override
  void initState() {
    super.initState();
    getPrefs();
  }

  Future&lt;void&gt; getPrefs() async {
    //Get the int selected Color
    setState(() {});
  }

答案1

得分: 0

你遇到的问题是由于从SharedPreferences获取数据的异步性质引起的。为解决此问题,您可以在ColorProvider中创建一个名为init()的方法,并像这样调用它:

class ColorProvider with ChangeNotifier {
  int _selectedColor = 0;
  Color _mainColor = Colors.blue;
  bool _isInitialized = false;

  int get selectedColor => _selectedColor;

  set selectedColor(int index) {
    _selectedColor = index;
    _saveColor();
    notifyListeners();
  }

  Color get mainColor => _mainColor;

  Future<void> init() async {
    await _getColor();
    _isInitialized = true;
    notifyListeners();
  }

  Future<void> _saveColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt('_selectedColorKey', _selectedColor);
  }

  Future<void> _getColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final savedSelectedColor = prefs.getInt('_selectedColorKey');
    if (savedSelectedColor != null) {
      _selectedColor = savedSelectedColor;
    }
  }

  // 其余的代码
}

然后像这样调用init()

@override
void initState() {
  super.initState();
  Provider.of<ColorProvider>(context, listen: false).init();
}

愉快的编码!

英文:

The problem you have, is due to the asynchronous nature of getting data from SharedPreferences.for solving this issue you can create a method named init() in ColorProvider and call it like this:

class ColorProvider with ChangeNotifier {
  int _selectedColor = 0;
  Color _mainColor = Colors.blue;
  bool _isInitialized = false;

  int get selectedColor =&gt; _selectedColor;

  set selectedColor(int index) {
    _selectedColor = index;
    _saveColor();
    notifyListeners();
  }

  Color get mainColor =&gt; _mainColor;

  Future&lt;void&gt; init() async {
    await _getColor();
    _isInitialized = true;
    notifyListeners();
  }

  Future&lt;void&gt; _saveColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setInt(&#39;_selectedColorKey&#39;, _selectedColor);
  }

  Future&lt;void&gt; _getColor() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final savedSelectedColor = prefs.getInt(&#39;_selectedColorKey&#39;);
    if (savedSelectedColor != null) {
      _selectedColor = savedSelectedColor;
    }
  }

  // the rest of your code
}

and call init() like this:

@override
void initState() {
  super.initState();
  Provider.of&lt;ColorProvider&gt;(context,listen:false).init();
}

happy coding...

huangapple
  • 本文由 发表于 2023年5月22日 03:11:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301516.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定