Home > Mobile >  Change a value from a List item and mantain it when changing pages on a page view
Change a value from a List item and mantain it when changing pages on a page view

Time:01-28

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.

  1. Declare isLockedList outside the build method as a nullable.
  2. Set isLockedList only when the value is null in the StreamBuilder.

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);
     }
     ....
   }
 );
 ....
}
  •  Tags:  
  • Related