I get the length of the data in a page view.builder and then generate a List with all values being false (quantity = data length):
List<bool> isLockedList = List.generate(dataLength, (index) => false);
On a GestureDetector, on onTap, I have:
onTap: () {
setState(() {
isLockedList[index] = true;
});
print(isLockedList);
}
When I click on the item index 0 from the page view builder, which the length is 2, the List changes to [true, false]. When I go index 1, it changes to [false, true]. Why isn't it changing to [true, true]. Wasn't the value supposed to be overwritten?
When I change pages, without using the onTap, the List is reset to default values [false,false]
Entire code:
late final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance
.collection('systems')
.doc(widget.systemRef)
.collection('matters')
.doc(widget.matterRef)
.collection('questions')
.snapshots();
@override
Widget build(BuildContext context) {
mediaQuery = MediaQuery.of(context).size;
int totalQuestion = 0;
int currentQuestion = 0;
return StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Scaffold(
body: Center(
child: Text('Algo deu errado'),
),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
int dataLength = snapshot.data!.docs.length;
List<bool> isLockedList = List.generate(dataLength, (index) => false);
return Scaffold(
appBar: AppBar(
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
leading: Navigator.canPop(context)
? IconButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
icon: const Icon(
Icons.chevron_left,
color: Colors.black,
size: 40,
),
onPressed: () => Navigator.of(context).pop(),
)
: null,
actions: [
Padding(
padding: EdgeInsets.only(right: mediaQuery.width *0.05),
child: Center(child: Text('$currentQuestion /$totalQuestion', style: const TextStyle(color: Colors.black),)),
),
],
),
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: PageView.builder(
onPageChanged: (value) {
print(isLockedList);
},
controller: _pageController,
itemCount: dataLength,
itemBuilder: (ctx, index) {
refIndex = index;
currentQuestion = index 1;
totalQuestion = dataLength;
QueryDocumentSnapshot<Object?> output =
snapshot.data!.docs[index];
List<String> alternativesCode = List<String>.generate(
output['numberOfOptions'],
(int index) => 'option${index 1}.code');
List<String> alternativesText = List<String>.generate(
output['numberOfOptions'],
(int index) => 'option${index 1}.text');
imageUrl = output['image'];
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.05),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SizedBox(
// width: mediaQuery.width,
// child: Text(
// '${index 1}/$dataLength',
// textAlign: TextAlign.end,
// style: const TextStyle(
// fontSize: 18, fontWeight: FontWeight.w600),
// ),
// ),
Container(
constraints: BoxConstraints(
maxHeight: mediaQuery.height * 0.16,
minHeight: mediaQuery.height * 0.05),
child: AutoSizeText(
output['title'],
maxLines: 4,
textAlign: TextAlign.start,
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 23),
),
),
SizedBox(height: mediaQuery.height * 0.03),
const SizedBox(
height: 10,
),
imageUrl.isNotEmpty
? Container(
alignment: Alignment.center,
child: Image.network(imageUrl,
height: mediaQuery.height * 0.2))
: SizedBox(
height: mediaQuery.height * 0.05,
),
SizedBox(
height: mediaQuery.height * 0.03,
),
Container(
constraints:
BoxConstraints(maxHeight: mediaQuery.height * 0.1, maxWidth: mediaQuery.width * 0.9),
child: AutoSizeText(
output['subtitle'],
maxLines: 2,
textAlign: TextAlign.start,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
fontStyle: FontStyle.italic),
),
),
SizedBox(
height: mediaQuery.height * 0.02,
),
Container(
height: mediaQuery.height * 0.37,
width: double.infinity,
color: Colors.white,
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: alternativesText.length,
itemBuilder: (ctx, i) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: GestureDetector(
child: Container(
height: mediaQuery.height * 0.07,
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Colors.grey,
blurRadius: 3,
// Shadow position
),
],
border: Border.all(
width: 3, color: Colors.grey),
borderRadius: BorderRadius.circular(10),
color: Colors.grey[100],
),
// width: mediaQuery.width,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10),
child: Row(
children: [
Text(
'${output[alternativesCode[i]]}',
style: TextStyle(
color: Colors.grey.shade800,
fontWeight: FontWeight.w600,
fontSize: 20),
),
Container(
padding:
const EdgeInsets.only(left: 5),
alignment: Alignment.centerLeft,
width: mediaQuery.width * 0.78,
height: mediaQuery.height * 0.07,
// constraints: BoxConstraints(maxWidth: mediaQuery.width * 0.8, minWidth: mediaQuery),
child: AutoSizeText(
output[alternativesText[i]],
maxLines: 2,
textAlign: TextAlign.justify,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 15),
),
),
],
),
),
),
onTap: () {
setState(() {
isLockedList[index] = true;
});
print(isLockedList);
}),
);
},
),
),
],
),
);
},
),
),
),
);
},
);
}
}
CodePudding user response:
Follow this steps.
- Declare
isLockedListoutside the build method as a nullable. - Set
isLockedListonly when the value is null in theStreamBuilder.
Code:
List<bool>? isLockedList;
@override
Widget build(BuildContext context){
....
return StreamBuilder<QuerySnapshot>(
builder: (context, snapshot) {
...
if (snapshot.hasError) {
return const Scaffold(
body: Center(
child: Text('Algo deu errado'),
),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
int dataLength = snapshot.data!.docs.length;
if(isLockedList == null){
isLockedList = List.generate(dataLength, (index) => false);
}
....
}
);
....
}
