【问题标题】:Flutter set state not updating the UI valueFlutter 设置状态不更新 UI 值
【发布时间】:2021-05-26 03:32:38
【问题描述】:

我有两个屏幕。

  1. 订阅页面
  2. 货币列表

订阅页面 此页面有 3 个计划。免费、中等和专业版。我会显示每个计划的价格。

货币页面 这个页面你可以选择你的货币。美元、欧元、瑞士法郎等,

我的问题是,当我在货币页面中更改货币并返回订阅页面时。状态值没有更新。

Future<dynamic> loadSubscriptionAsset() async {
  var response = await http.get(
      Uri.encodeFull('http://localhost.com/api/subscription'),
      headers: {
        "Accept": "application/json"
      }
  );

  return response.body;
}
    
// State Variables 
  var subscriptionData;
  var freePrice = '0.00';
  var mediumPrice = '0.00';
  var premiumPrice = '0.00';
  final LocalStorage storage = new LocalStorage('currentCurrencyState');
  final LocalStorage priceStorage = new LocalStorage('priceInfoState');

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

    setPrice();
            
  }

  setPrice(){        
    setState(() {
      loadSubscriptionAsset().then((value) {
        print('set');
        print(DateTime.now());
        value = jsonDecode(value);
        subscriptionData = value;
        if(storage.getItem('currentCurrency')==''){
          var defaultCurrency = subscriptionData['currency']['usd']['id'];
          var prices = subscriptionData['price'];
          freePrice = prices["1"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          mediumPrice = prices["2"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          premiumPrice = prices["3"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          priceStorage.setItem('freePrice',freePrice);
          print('free price '+freePrice);
        }
        else{
          var defaultCurrency = storage.getItem('currentCurrency');
          var prices = subscriptionData['price'];
          freePrice = prices["1"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          mediumPrice = prices["2"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          premiumPrice = prices["3"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
          priceStorage.setItem('freePrice',freePrice);
          print('free price '+freePrice);
        }
      });
    });
  }


@override
  Widget build(BuildContext context) {

    setPrice();

    return WillPopScope(..

那么,问题出在哪里 print('free price '+freePrice);当我在订阅页面和货币页面之间导航时,此行打印值。但在应用 UI 中,状态值没有更新。

示例: 中型计划 USD - 10 中型计划 EUR - 15

在这种情况下。当我将货币从美元转换为欧元时。在我的代码中它工作正常,我可以在打印中看到值,但应用程序屏幕未更新。它仍然是美元货币。

当我在选项卡之间切换或单击应用程序屏幕时,这些值会发生变化。直到它不更新视图。


我忘了提一个问题。那是。您可以在应用程序屏幕中看到 $ 图标。如果您单击它,它将转到货币列表图像。一旦您更改货币并返回订阅页面。 initState 没有调用。所以货币没有更新。我不知道如何解决这个问题,所以我在

中调用了 setPrice() 函数
@override
  Widget build(BuildContext context) {

    setPrice();

    return WillPopScope(

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies


    【解决方案1】:

    由于loadSubscriptionAsset 是异步的,因此在代码中该函数完成之前调用 setState。相反,您需要在函数完成后调用它。您可以链接.then 或在未来完成后像这样放置状态:

    setPrice(){    
        loadSubscriptionAsset().then((value) {
        setState(() {
            print('set');
            print(DateTime.now());
            value = jsonDecode(value);
            subscriptionData = value;
            if(storage.getItem('currentCurrency')==''){
                var defaultCurrency = subscriptionData['currency']['usd']['id'];
                var prices = subscriptionData['price'];
                freePrice = prices["1"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                mediumPrice = prices["2"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                premiumPrice = prices["3"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                priceStorage.setItem('freePrice',freePrice);
                print('free price '+freePrice);
            }
            else{
                var defaultCurrency = storage.getItem('currentCurrency');
                var prices = subscriptionData['price'];
                freePrice = prices["1"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                mediumPrice = prices["2"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                premiumPrice = prices["3"][defaultCurrency.toString()].toString()+' '+subscriptionData['currency']['usd']['code'].toString();
                priceStorage.setItem('freePrice',freePrice);
                print('free price '+freePrice);
            }
            });    
        });
        
      }
    

    【讨论】:

    • 它有效,谢谢。我是新来的。我只是担心 then() 函数中的 setState 方法是否正确。
    • 嗨,我还有一个疑问。在货币列表页面中。从 api 加载结果需要时间。只需 2 3 秒。所以每次当你访问这个页面时,它都会从 api 加载。相反,是否有缓存结果并首先加载,直到它从 api 获得结果?
    • @SoundharRaj 这应该是一个单独的问题。创建一个新问题并包含整个小部件,然后将链接粘贴到此处以便我查看。如果它解决了您的问题,请将此答案标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多