我是新手。在我的项目中,根据列表(出席者列表)的长度,会有各种check_list_tile
。而且我使用了一个布尔变量。现在,当我按下一个复选框时,它会自动选中所有其他复选框。请对此提供帮助(点击一个复选框不应更改除单击之外的所有其他复选框的状态)。我已经复制了所有代码,请检查check_box_list
字段。
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'dart:async';
Map map_student_data;
Iterable iter_student_data,iter_student_key;
List list_student_data,list_student_key;
bool t=true,checkbox=false;
List list;
String validation="yes";
int i;
int year;
final FirebaseDatabase database = FirebaseDatabase.instance;
class IImca_attendence extends StatefulWidget {
@override
_IImca_attendenceState createState() => _IImca_attendenceState();
}
class _IImca_attendenceState extends State<IImca_attendence> {
@override
void initState(){
this.check_year();
super.initState();
}
DateTime date = DateTime.now();
Future check_year()async{
var k= await database.reference().child("NITTE/CLASS/MCA").once().then((DataSnapshot snapshot){
Map sea= snapshot.value;
Iterable iter=sea.keys;
list=iter.toList();
list.sublist(list.length-1);
list.sort();
setState(() {
year=list.length-2;
});
check();
});
}
Future check()async{
var m=await database.reference().child("NITTE/CLASS/MCA/${list[year].toString().toUpperCase()}/STUDENT").once().then((DataSnapshot currentyear){
map_student_data=currentyear.value;
iter_student_data=map_student_data.values;
iter_student_key=map_student_data.keys;
list_student_data=iter_student_data.toList();
list_student_key=iter_student_key.toList();
for(i=0;i<=list_student_data.length;i++){
bool ss=true;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("II-MCA"),
centerTitle: true,
actions: <Widget>[
IconButton(icon: Icon(Icons.refresh),onPressed: (){
setState(() {
check_year();
});
})
],
),
body:
validation=="1"?
new Center(
child: Text("STUDENT DOSE NOT EXIST IN $year",style: TextStyle(color: Colors.grey,fontWeight: FontWeight.bold,fontSize: 20),),
):
new ListView.builder(
itemCount: list_student_data==null?0
:list_student_data.length,
itemBuilder: (BuildContext context,int index){
var student_detail= ['NAME : ${list_student_data[index]['NAME']}','GENDER : ${list_student_data[index]['CURRENT CLASS']}','PHOTO : ${list_student_data[index]['PHOTO']}'];
return new Container(
child: new Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: CheckboxListTile(
title: Text("${list_student_key[index]}",style:TextStyle(fontWeight: FontWeight.bold,),),
subtitle: Text("NAME : ${list_student_data[index]['NAME']}"),
value: checkbox,
onChanged: (val){
setState(() {
checkbox=val;
if(checkbox==true){
print("${list_student_data[index]['NAME']}: i am absent");
}if(checkbox==false){
print("${list_student_data[index]['NAME']}: i am present");
}
});
},
),
padding: EdgeInsets.all(5),
),
)
],
),
),
);
}
)
);
}
}
答案 0 :(得分:2)
嗯...您正在使用全局 checkbox
变量,因此,如果更改它,根据其状态,所有小部件都会相应地更改。
我建议您做的是在模型类中添加selected
状态。举个例子,假设您有这个学生班(我知道您正在使用Firebase,但是为了时间我没有)
class Student {
var name = 'foo';
var year = '2018';
var selected = false;
Student(this.name);
}
该类的内部为selected
状态。
现在假设您的快照给您3个学生。总是为了节省时间,我嵌入了本地数组:
class _IImca_attendenceState extends State<IImca_attendence> {
var _students = [Student('foo'), Student('pub'), Student('beer')];
...
(省略号不是代码的一部分...;-])
我建议您将状态变量放在有状态窗口小部件作用域内,而不要放在全局作用域内。
说你可以:
ListView.builder(
itemCount: _students.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: CheckboxListTile(
title: Text(
_students[index].name,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle:
Text("NAME : ${_students[index].name}"),
value: _students[index].selected,
onChanged: (val) {
setState(() {
_students[index].selected = val;
if (!_students[index].selected) {
print(
'${_students[index].name}: i am absent');
}
if (_students[index].selected) {
print(
'${_students[index].name}: i am present');
}
});
},
),
padding: EdgeInsets.all(5),
),
)
],
),
),
);
}
)
您还应该使用与快照数据学生数组长度相同的bool数组...但是我建议您直接在您的Student
模型上跟踪此信息。
更新
随着您对数组的使用更加舒适,我已经使用与学生列表大小相同的补充array of bool
来更改代码。
您所要做的就是一个布尔值数组(不是单个值),其布尔值与学生数组的大小相同,让我们称之为list_student_present
(我改用list_student_present2
)
开始时,您以check function
的方式初始化它:
list_student_data = iter_student_data.toList();
// This is the array you wanna use (first all false)
list_student_present = iter_student_data.map((_) => false).toList();
然后您将使用以下布尔数组检查复选框的状态:
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: CheckboxListTile(
title: Text(
_students[index].name,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle:
Text("NAME : ${_students[index].name}"),
value: list_student_present[index],
onChanged: (val) {
setState(() {
list_student_present[index] = val;
if (!list_student_present[index]) {
print(
'${_students[index].name}: i am absent');
}
if (list_student_present[index]) {
print(
'${_students[index].name}: i am present');
}
});
},
),
padding: EdgeInsets.all(5),
),
)
],
),
),
);
}
请勿使用我的学生班级(我将继续使用它,以便能够在不使用Firebase的情况下向您显示数据),请继续使用Firebase快照中的学生数组列表。
完整代码:
import 'package:flutter/material.dart';
import 'dart:async';
Map map_student_data;
Iterable iter_student_data, iter_student_key;
List list_student_data, list_student_key, list_student_present, list_student_present2;
bool t = true;
List list;
String validation = "yes";
int i;
int year;
class Student {
var name = 'foo';
var year = '2018';
var selected = false;
Student(this.name);
}
class IImca_attendence extends StatefulWidget {
@override
_IImca_attendenceState createState() => _IImca_attendenceState();
}
class _IImca_attendenceState extends State<IImca_attendence> {
var _students = [Student('foo'), Student('pub'), Student('beer')];
@override
void initState() {
this.check_year();
super.initState();
}
DateTime date = DateTime.now();
Future check_year() async {
Map sea = {1: 'atlantic', 2: 'pacific'};
Iterable iter = sea.keys;
list = iter.toList();
list.sublist(list.length - 1);
list.sort();
setState(() {
year = list.length - 2;
});
check();
}
Future check() async {
map_student_data = {
0: {'NAME': 'foo', 'CURRENT CLASS': 'pub', 'PHOTO': ''}
};
iter_student_data = map_student_data.values;
iter_student_key = map_student_data.keys;
list_student_data = iter_student_data.toList();
// This is the array you wanna use
list_student_present = iter_student_data.map((_) => false).toList();
// This is the array for my example
list_student_present2 = _students.map((_) => false).toList();
list_student_key = iter_student_key.toList();
for (i = 0; i <= list_student_data.length; i++) {
bool ss = true;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("II-MCA"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
setState(() {
check_year();
});
})
],
),
body: validation == "1"
? new Center(
child: Text(
"STUDENT DOSE NOT EXIST IN $year",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.bold,
fontSize: 20),
),
)
: ListView.builder(
itemCount: _students.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Card(
child: new Container(
child: CheckboxListTile(
title: Text(
_students[index].name,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle:
Text("NAME : ${_students[index].name}"),
value: list_student_present2[index],
onChanged: (val) {
setState(() {
list_student_present2[index] = val;
if (!list_student_present2[index]) {
print(
'${_students[index].name}: i am absent');
}
if (list_student_present2[index]) {
print(
'${_students[index].name}: i am present');
}
});
},
),
padding: EdgeInsets.all(5),
),
)
],
),
),
);
}));
}
}
我真的不喜欢这种解决方案。我建议您创建代表您的Firebase模型的PODO(纯旧Dart对象),并从Firebase快照中反序列化它们。