Home > Software design >  Widget doesn't change, although new state is called
Widget doesn't change, although new state is called

Time:01-25

I wanted to have a text, that changes every time one of the filter cards is selected/deselected. I made a global variable (I don't know what the best way to do that is but to me it seemed like it should work) and changed the value of it every time one of the filter cards was tapped. The problem is that the text widget, where the value is supposed to be displayed, doesn't change although the output shows, that the set state function worked. For more info see the pictures and code below.

Future<dynamic> filterMealsAndWines(BuildContext context) {
final appliedFilters = ValueNotifier(0);
return showModalBottomSheet(
  context: context,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(35),
  ),
  builder: (BuildContext context) {
    return Stack(
      children: [
        Container(
          height: 377,
          width: 390,
          decoration: BoxDecoration(
              color: primaryColor, borderRadius: BorderRadius.circular(35)),
        ),
        Positioned(
          top: 312,
          child: Container(
            height: 65,
            width: 390,
            decoration: const BoxDecoration(
              color: secondaryTextColor,
            ),
          ),
        ),
              Positioned(
                left: 110,
                top: 15,
                child: Container(
                  height: 9,
                  width: 20,
                  decoration: BoxDecoration(
                    color: primaryColor,
                    borderRadius: BorderRadius.circular(
                      20,
                    ),
                  ),
                  child: ValueListenableBuilder(
                    valueListenable: appliedFilters,
                    builder: (context, appliedFilters, _) {
                      return Center(
                        child: Text(
                          appliedFilters.toString(),
                          style: GoogleFonts.poppins(
                            textStyle: const TextStyle(
                              color: mainTextColor,
                              fontSize: 6,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  },
);

} }

Widget Output

CodePudding user response:

Solution is that you have to wrap your stack widget inside the modal bottom sheet with a StatefulBuilder widget example:

 StatefulBuilder: (context, setState) {
 return Stack(....) ;
  }

https://api.flutter.dev/flutter/widgets/StatefulBuilder-class.html

upvote if helpful

CodePudding user response:

If this widget, is the widget you are trying to update when setState() is called, it doesn't work because it is not in same StatefulWidget as the setState() function in result the widget doesn't rebuild.

child: Center(
  child: Text(
    appliedFilters.toString(),
    style: GoogleFonts.poppins(
      textStyle: const TextStyle(
        color: mainTextColor,
        fontSize: 6,
        fontWeight: FontWeight.w600,
      ),
    ),
  ),
),   

To solve you should read more about state managment in Flutter, but a temporary solution could be using a ValueListenableBuilder

So you should wrap your Text widget in ValueListenableBuilder and your your value appliedFilters will update the builder whenever it is changed

Future<dynamic> filterMealsAndWines(BuildContext context){
  ValueNotifier<int> appliedFilters = ValueNotifier(0); 

  //Your all previuos code 

  ValueListenableBuilder<int>(
    valueListenable: appliedFilters,
    builder: (context, value, _) {
      return Center(
        child: Text(
          appliedFilters.toString(),
          style: GoogleFonts.poppins(
            textStyle: const TextStyle(
              color: mainTextColor,
              fontSize: 6,
              fontWeight: FontWeight.w600,
            ),
          ),
        ),
      );
    }
  ),
}

class FilterSelectCardState extends State<FilterSelectCard> {

  //pass this value to FilterSelectCard
  ValueNotifier<int> appliedFilters = widget.appliedFilters; 

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(
        right: 12,
      ),
      child: GestureDetector(
        onTap: () {
          setState(() {
            //HERE YOU UPDATE THE VALUE
            appliedFilters.value  = 1;
          });
        },
      ),

      //all your other code

    );
  }
}
  •  Tags:  
  • Related