微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在单独的窗口小部件更新中更新状态

如何解决在单独的窗口小部件更新中更新状态

我试图弄清楚按下按钮时如何更新小部件的状态。

以下是一些屏幕截图,以说明我要完成的工作:

enter image description here

enter image description here

热重新加载应用程序时,更新生效,但是当我按下对话框上的更新按钮时,状态不会更新。

我知道有很多技术可以使它起作用,但我无法通过将函数传递给构造函数来使其更新。

我也不太想知道如何使用provider.of(context)而不传递一些值。这两个地方(mainDebt小部件和allDebts小部件)都没有使用任何值。

主页代码非常简单。一个无状态小部件,其中包含我需要显示的不同小部件:

class Home extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),),body: SingleChildScrollView(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
              SizedBox(
                height: 30,HpHeader(),SizedBox(height: 30),QuoteBox(),MainDebtDebt(),AdCard(),AllDebtsCard(),SizedBox(height: 10),RaisedButton(
                  child: Text('Enter Debt'),onpressed: () => Navigator.pushNamed(context,'/enterDebt1')),//etc........

mainDebtDebt是我需要更新状态的小部件。它是从SharedPreferences中读取数据,该数据是在我按下对话框上的更新按钮时设置的:

import 'dart:async';

//import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:debt_zero_2/classes/icon_class.dart';
import 'package:Flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class MainDebtDebt extends StatefulWidget {

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

class _MainDebtDebtState extends State<MainDebtDebt> {
   
   bool thenum = true;

  static DebtModel debtIcons = DebtModel();
  bool getGoalType = true;
  double balance = 0.0;
  String name = '';
  String type = ''; 
  int numOfDebts = 0;
  double safetyBalance = 0.0;

  double mainsnowballopeningBalance = 0.0;

 

  Future<void> getGoalTypeFlag() async {
    final SharedPreferences preferences = await SharedPreferences.getInstance();
    final sortBy = preferences.getInt('sortBySNowOrAva');
    setState(() {
       if (sortBy == 1){
      balance = preferences.getDouble('mainDebtFieldsnowball');
      type = preferences.getString('mainDebtFieldsnowballType');
      name = preferences.getString('mainDebtFieldsnowballName');}

       if (sortBy == 2){
      balance = preferences.getDouble('mainAvalancheBalance');
      type = preferences.getString('mainAvalancheBalanceType');
      name = preferences.getString('mainAvalancheBalanceName');
       }

      mainsnowballopeningBalance = preferences.getDouble('openingBalance');  

      safetyBalance = preferences.getDouble('safetyBalance');
      getGoalType = preferences.getBool('mainGoalIsDebts');
      numOfDebts = preferences.getInt('numberOfDebts');     
    
    });
  }



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

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,decoration: Boxdecoration(border: Border.all()),child: Column(
        children: <Widget>[
          Text(getGoalType
              ? 'I\'m Knocking Out This Payment:'
              : 'I\'m Building My Safety Fund'),SizedBox(
            height: 15,Row(
            mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
              Text(
                getGoalType
                    ? debtIcons.getDebtIcon(type)
                    : '?',style: TextStyle(fontSize: 30),SizedBox(
                width: 20,Text(getGoalType ? name : 'Safety Fund'),],children: <Widget>[
              Text(getGoalType ? 'Remaining Balance:' : 'Saved:'),SizedBox(
                width: 15,Text(getGoalType
                  ? '\$' + balance.toStringAsFixed(0)
                  : safetyBalance.toStringAsFixed(0))
            ],Column(
            children: <Widget>[
              Text('Current Progress:'),SizedBox(
                height: 10,Container(
                decoration: Boxdecoration(border: Border.all()),height: 22,width: 202,child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
                    Flexible(
                      child: FractionallySizedBox(
                        widthFactor: .75,//fix this
                        // 1 - mainsnowballBalance / mainsnowballopeningBalance,child: Container(
                          color: Colors.green,)
                  ],SizedBox(
                height: 15,RaisedButton(
                child: Text(getGoalType ? 'MAKE A PAYMENT' : 'MAKE A DEPOSIT'),onpressed: () {
                  Navigator.of(context).pushNamed('/makePayment');
                },SizedBox(
                height: 30,RaisedButton(
                child: Text('GET DATA'),onpressed: ()async {
                 
                  SharedPreferences pref = await SharedPreferences.getInstance();
                      

                    String thenum = pref.getString('debtId');
                    //pref.setBool('isInOb',null);
                    print(thenum);
                  
                },)
        ],);
  }
}

排序对话框当前位于AllDebtsCard中。当前,它可以按最高利息或最低余额分别对列表进行排序:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:debt_zero_2/classes/min_debt_class.dart';
//import 'package:debt_zero_2/classes/icon_class.dart';
import 'package:debt_zero_2/widgets/provider_widget.dart';
import 'package:Flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AllDebtsCard extends StatefulWidget {
  @override
  _AllDebtsCardState createState() => _AllDebtsCardState();
}

class _AllDebtsCardState extends State<AllDebtsCard> {
  int debtValue = 1;

  int group;

  void setValues() async {
    SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
    final uid = await Provider.of(context).auth.getUidPref();
    final db = Firestore.instance;
    setState(() {
      sharedPrefs.setInt('sortBySNowOrAva',debtValue);
      SetMainDebt().setMainDebt();
    });

    db
        .collection('userPreferences')
        .document(uid)
        .updateData({'sortBySNowOrAva': debtValue});
  }

  getValues() async {
    SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
    int intValue = sharedPrefs.getInt('sortBySNowOrAva');

    return intValue;
  }

  restore() async {
    final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
    setState(() {
      group = (sharedPrefs.getInt('sortBySNowOrAva') ?? false);
    });
  }

  final dbPath = Firestore.instance.collection('userDebts');

  Stream<QuerySnapshot> dbStream(BuildContext context) async* {
    final uid = await Provider.of(context).auth.getUidPref();
    final intValues = await getValues();
    yield* intValues == 1
        ? dbPath
            .document(uid)
            .collection('debts')
            .orderBy('balance')
            .snapshots()
        : dbPath
            .document(uid)
            .collection('debts')
            .orderBy('interest',descending: true)
            .snapshots();
  }

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        RaisedButton(
          child: Text('SORT'),onpressed: () {
            showDialog(
                barrierdismissible: false,context: context,builder: (BuildContext context) {
                  return StatefulBuilder(
                    builder: (context,setState) {
                      return AlertDialog(
                        title: Text('Sort Debts By:'),content: Column(
                          mainAxisSize: MainAxisSize.min,children: <Widget>[
                            RadioListTile(
                              value: 1,secondary: IconButton(
                                onpressed: () {
                                  showDialog(
                                      context: context,builder: (BuildContext context) {
                                        return AlertDialog(
                                          title: Text('Debt snowball:'),content: Text(
                                              'This is an explanation of debt snowball'),actions: <Widget>[
                                            FlatButton(
                                              child: Text('OK'),onpressed: () {
                                                Navigator.pop(context);
                                              },)
                                          ],);
                                      });
                                },icon: Icon(Icons.help_outline),title: Text('snowball'),groupValue: group,onChanged: (T) {
                                setState(() {
                                  group = T;
                                  debtValue = 1;
                                });
                              },RadioListTile(
                              value: 2,title: Text('Avalanche'),secondary: IconButton(
                                onpressed: () {},onChanged: (T) {
                                setState(() {
                                  group = T;
                                  debtValue = 2;
                                });
                              },)
                          ],actions: <Widget>[
                          FlatButton(
                            onpressed: () async {
                              setState(() {
                                setValues();
                              });
                              Navigator.pop(context);
                            },child: Text('UPDATE'),FlatButton(
                            child: Text(
                              'CANCEL',style: TextStyle(color: Colors.red),onpressed: () {
                              Navigator.pop(context);
                            },);
                    },);
                }).then((value) => setState(() {}));
          },StreamBuilder<QuerySnapshot>(
            stream: dbStream(context),builder: (context,snapshot) {
              if (snapshot.hasData) {
                final debts = snapshot.data.documents;
                List<Widget> debtWidgets = [];
                for (var debt in debts) {
                  final debtName = debt.data['name'];
                  final debtType = debt.data['type'];
                  final debtBalance = debt.data['balance'];
                  final debtDue = debt.data['due'].toDate();

                  final debtWidget = Card(
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[
                        Text('$debtType'),Text('$debtName'),Text(DateFormat.MMMd().format(debtDue)),Text('$debtBalance'),FlatButton(
                          child: Text(
                            'DELETE',onpressed: () {
                            //When I delete a debt I need to update the 'debtMinimum' field in prefs and firestore
                          },)
                      ],);

                  debtWidgets.add(debtWidget);
                }
                return Column(children: debtWidgets);
              }
              return Container();
            }),);
  }
}

我不反对尝试任何可行的技术。提升状态,提供者或其他任何东西(不需要完全重建体系结构(我知道这不是非常好的东西))。 我已经尝试了好几天来解决这个问题。任何帮助将不胜感激。谢谢

解决方法

您可以包装窗口小部件以使用StreamBuilder更新,然后在按下RaisedButton时将事件发送到流接收器。下面是简单的示例:

/// Some where in State class
class _SomeWidgetState extends State<SomeWidget> {
  /// Stream controller which takes integer identifiers
  StreamController<int> streamController;

  /// Result stream which converts int to UpdatableObject via function
  Stream<UpdatableObject> get stream => streamController.stream.asyncMap(_getObjectById);

  /// Takes object identifier and returns corresponding object.
  Future<UpdatableObject> _getObjectById(int id) {
    ...
    return UpdatableObject();
  }

  @override
  void initState() {
    super.initState();
    // Take from parent `Provider` widget
    streamController = Provider.of<int>(context,listen: false);
    // or create it here (depends on requirements)
    //streamController = StreamController<int>.broadcast();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<UpdatableObject>(
      stream: stream,builder: (context,snapshot) {
        if (snapshot.hasError) {
          return Text(snapshot.error.toString();
        }
        if (!snapshot.hasData) {
          return CircularProgressIndicator();
        }
        // `snapshot.data` contains instance of `UpdatableObject`
        return TheWidgetToBeUpdated(data: snapshot.data); 
      }
    );
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。