检查 ListView 中的一个 CheckBox 使用 Flutter 来检查所有其余的 CheckBox
Posted
技术标签:
【中文标题】检查 ListView 中的一个 CheckBox 使用 Flutter 来检查所有其余的 CheckBox【英文标题】:Checking one CheckBox in a ListView checks all of the rest using Flutter 【发布时间】:2020-09-07 15:00:33 【问题描述】:我对 Flutter 和 *** 完全陌生。事实上,这是我的第一个问题,所以如果我完全没有提出这个问题,请原谅我。我正在尝试制作一个简单的 Flutter 应用程序,它提供问题的 ListView 和每个问题旁边的复选框。然后用户可以选择他们想要回答的问题。我的问题是,当用户选中任何复选框时,所有复选框都会被选中,反之亦然。问题本身是从无后端数据库中检索的。下面的代码是我到目前为止所拥有的。任何人都可以为我提供任何帮助,我将不胜感激。
import 'package:flutter/material.dart';
class Questions extends StatefulWidget
final List<Map> questionList;
Questions(this.questionList);
@override
_QuestionsState createState() => _QuestionsState();
class _QuestionsState extends State<Questions>
bool _questionSelected = true;
Widget _buildQuestionItem(BuildContext context, int index)
return ListTile(
title: Text(widget.questionList[index]['question']),
trailing: Checkbox(
value: _questionSelected,
onChanged: (bool val)
setState(()
_questionSelected = val;
);
,
),
);
@override
Widget build(BuildContext context)
return ListView.builder(
padding: EdgeInsets.all(10),
itemBuilder: _buildQuestionItem,
itemCount: widget.questionList.length,
);
更新:
感谢 Mohammed Ashab Uddin 的建议我觉得我已经接近让这个东西工作但我仍然收到错误
"RangeError(index):无效值:有效值范围为空:0"
我想我应该在我设置 questionList 值的地方发布 main.dart 代码,也许它是导致此错误的代码执行顺序,所以请在下面找到我的 main.dart 代码,希望它会有所帮助解决这个问题。
import 'package:flutter/material.dart';
import 'package:backendless_sdk/backendless_sdk.dart';
import 'package:flutter/rendering.dart';
import 'questions.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'RT Database Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Questions'),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State
static const String API_HOST = "https://api.backendless.com";
static const String APP_ID = "<APP_ID>";
static const String android_APP_KEY = "<ANDROID_APP_KEY>";
static const String ios_APP_KEY = "<IOS_APP_KEY>";
IDataStore<Map> questionsStore = Backendless.data.of('Questions');
List<Map> questionsList = [];
var _questionSelected = false;
@override
void initState()
super.initState();
_initBackendless();
_enableRealTime();
getQuestions();
void _initBackendless()
Backendless.setUrl(API_HOST);
Backendless.initApp(APP_ID, ANDROID_APP_KEY, IOS_APP_KEY);
void _enableRealTime()
EventHandler<Map> rtHandlers = questionsStore.rt();
rtHandlers.addCreateListener((question)
setState(()
questionsList = List.from(questionsList);
questionsList.add(question);
);
);
rtHandlers.addUpdateListener((question)
setState(()
questionsList = List.from(questionsList
.map((m) => m['objectId'] == question['objectId'] ? question : m));
);
);
rtHandlers.addDeleteListener((question)
setState(()
questionsList = List.from(questionsList);
questionsList.removeWhere((m) => m['objectId'] == question['objectId']);
);
);
void _selectQuestion(bool newValue)
setState(()
_questionSelected = newValue;
);
void getQuestions()
DataQueryBuilder queryBuilder = DataQueryBuilder()
..pageSize = 100
..sortBy = ['created'];
questionsStore
.find(queryBuilder)
.then((response) => setState(() => questionsList = response));
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text("My Life History"),
),
body: FractionallySizedBox(
heightFactor: 0.5,
child: Questions(questionsList),
),
);
【问题讨论】:
【参考方案1】:变量_questionSelected
是一个全局变量。所有复选框小部件都使用此变量作为值。因此,当onChanged()
函数上的变量发生变化时,所有的值也会变为_questionSelected
的值。
在这种情况下,您需要跟踪复选框小部件的所有值。因此,您应该使用数组而不是单个变量。
我通常做的是,创建一个仅包含所选元素的新列表。 如果一个元素没有被选中,则删除它,如果它被选中,则添加一个元素。
//generate a list of false values with the length of questionList
List<bool> _questionSelected;
initState()
_questionSelected = List<bool>.filled(questionList.length, false, growable: true);
super.initState();
Widget _buildQuestionItem(BuildContext context, int index)
return ListTile(
title: Text(widget.questionList[index]['question']),
trailing: Checkbox(
value: _questionSelected[index],
onChanged: (bool val)
setState(()
_questionSelected[index] = val;
);
,
),
);
【讨论】:
当我按照上面的建议编辑代码时,填充方法的长度变量出现错误。它说只有静态成员可以在初始化程序中访问。我尝试阅读该错误的 dart 诊断消息,但无法理解它的含义以及它如何应用于我的代码。 我忘了说你需要在initState()中初始化_questionSelected的值。我再次编辑了我的代码。 我收到一个 RangeError,我觉得这可能是因为代码执行的顺序。我忘记在我的原始帖子中包含调用 questions.dart 代码的 main.dart 代码。我编辑了帖子以包含该代码,希望它可以给出 RangeError 来源的一些指示。我自己想不通。我应该补充一点,如果我在代码的填充方法中用数字 3 替换“questionList.length”,它就可以工作。我感觉在 questions.dart 被调用的时候,questionList 没有被初始化。这就是为什么我还发布了调用 questions.dart 的 main.dart以上是关于检查 ListView 中的一个 CheckBox 使用 Flutter 来检查所有其余的 CheckBox的主要内容,如果未能解决你的问题,请参考以下文章
listView中带有复选框的自定义布局:当我删除一行时,如果选中它(checkBox = true),则下一行将获得检查
android中如何获得listview中的checkbox的值?
Android:将数据库中的数据绑定到 ListView 中的 CheckBox?
Android中ListView结合CheckBox判断选中项
Gridview, ListView中的item含有checkbox,setOnItemClickListener方法失效的问题