Flutter:点击位于子窗口小部件中的Textfield重建父窗口小部件并将列表留空

时间:2019-03-14 09:49:22

标签: dart flutter

我的应用程序上有一个“个人资料”标签。我称Future为将配置文件存储在sqflite数据库中,并将其存储在列表中并在卡中显示所有内容。

class ProfilePage extends StatefulWidget {
  @override
  _ProfilePageState createState() => new _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {

  TabController tabController;
  List<Patient> listOfPatients = List<Patient>();
  List<int> primaryKeys = List<int>();
  int profileCount = 0;
  final dbHelper = DatabaseHelper.instance;
  ....

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: _buildProfileTab(),
      ...........
    );
  }


Widget _buildProfileTab() {
    return FutureBuilder<dynamic>(
      future: _getAllProfiles(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.active:
          case ConnectionState.waiting:
            return Center(
              child: CircularProgressIndicator(),
            );
          case ConnectionState.done:
            return _createProfileCards();
        }
        return null; // unreachable
      },
    );
  }

  Future _getAllProfiles() async {
    listOfPatients.clear();
    primaryKeys.clear();
    await dbHelper.queryAllRows().then((allRows) {


      allRows.forEach((row) {

        //do some editing with the row and place the "temp" patient object in the list of patients list, and get it's id
        listOfPatients.add(temp);
        primaryKeys.add(row['_id']);
      });
    });

  }

  Widget _createProfileCards() {
    return ListView.builder(
      itemCount: listOfPatients.length,
      itemBuilder: (context, position) {
        return GestureDetector(
          onLongPress: () {
            ...........
            ...........     
          },
          child: Container(
            padding: position == listOfPatients.length - 1
                ? EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 80.0)
                : EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0),
            child: Card(
              elevation: 8.0,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(15.0),
              ),
              child: ListTile(
                contentPadding: EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0),
                leading: listOfPatients[position].gender == 0
                    ? CircleAvatar(
                        radius: 25.0,
                        backgroundColor: Colors.grey,
                        child: Icon(
                          MdiIcons.humanMale,
                          color: Colors.white,
                        ),
                      )
                    : CircleAvatar(
                        radius: 25.0,
                        backgroundColor: Colors.grey,
                        child: Icon(MdiIcons.humanFemale, color: Colors.white),
                      ),
                title: Text(
                  listOfPatients[position].name,
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
                ),
                subtitle: Text(listOfPatients[position].getAge() +
                    "\n" +
                    displayGenderString(listOfPatients[position].gender)),
                isThreeLine: true,
                trailing: IconButton(
                  icon: Text(
                    "VIEW",
                    style: TextStyle(
                      color: Color(0xFF2A8E5C),
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  onPressed: () {
                    if (listOfPatients.isNotEmpty) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => PatientPage(
                              listOfPatients[position], primaryKeys[position]), // this is where the error occurs when textfield is tapped
                        ),
                      );
                    }
                  },
                ),

              ),
            ),
          ),
        );
      },
    );
  }

一切正常。然后,当您点击个人资料卡中的“查看”图标按钮时,它会转到另一个有状态的小部件(PatientPage)-进入个人资料卡的更详细版本,并且它将对象患者传递给PatientPage使用。

在PatientPage中,我有一个ListTile,当用户想要使用一元运算符编辑“注释”部分时,我将其更改为文本字段。

Text(
                "Notes",
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 20.0,
                ),
              ),
              isNotesEditing
                  ? Column(
                      children: <Widget>[
                        TextField(
                          controller: notesEditController,
                        ),
                        ButtonBar(
                          alignment: MainAxisAlignment.center,
                          children: <Widget>[
                            FlatButton(
                              child: Text("SAVE"),
                              onPressed: () {
                                //update DB
                                widget.patientInfo.notes =
                                    notesEditController.text;
                                setState(() {
                                  isNotesEditing = false;
                                });
                              },
                            ),
                            FlatButton(
                              child: Text("CANCEL"),
                              onPressed: () {
                                setState(() {
                                  isNotesEditing = false;
                                });
                              },
                            )
                          ],
                        )
                      ],
                    )
                  : ListTile(
                      isThreeLine: true,
                      subtitle: Text(""),
                      trailing: IconButton(
                        icon: Icon(Icons.edit),
                        onPressed: () {
                           setState(() {
                            isNotesEditing = true;
                          }); 
                        },
                      ),
                      title: widget.patientInfo.notes == ""
                          ? Text("None")
                          : (widget.patientInfo.notes),
                    ),

我的问题是,当我点击文本字段时,ProfilePage(父窗口小部件)窗口小部件会重新生成(根据我使用断点的调查结果)。并产生错误“ RangeError(索引):无效值:有效值范围为空:0”。我不知道为什么它会像这样重建并且将listOfPatients留空。我什至在卡的onPressed回调中添加了检查功能,仅在列表不为空时才分配功能。

if (listOfPatients.isNotEmpty) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => PatientPage(
                              listOfPatients[position], primaryKeys[position]), // this is the part where flutter points out the invalid range
                        ),
                      );
                    }

感谢您的帮助。谢谢!

0 个答案:

没有答案