Home > Net >  Flutter Expansion Pannel not Expanding without immutable bool
Flutter Expansion Pannel not Expanding without immutable bool

Time:11-09

I have an expansion panel in _buildCategoryListings() that does not expand when the header or the dropdown button is clicked. isExpanded is set to the boolean categoryView.isExpanded. Through printing via the console I can see that the setState is actually updating the bool value but it looks like the actual widget isn't being redrawn perhaps? If I manually set isExpanded to true I see the results I want from the GUI. I also had set isExtended to theExpanded (which is in MovieListingView) which raises the issue of a mutable variable being in a class that extends StatefulWidget, this did give me the desired results though.

The question: How do I get the expansion panel to update the categoryView.isExpanded (via theListings[panelIndex].isExpanded) bool and show it via the GUI?

Thank you in advance.

Side note I thought about using a provider to keep track of this bool but that seems like overkill.

class MovieListingView extends StatefulWidget {
  @override
  _MovieListingView createState() => _MovieListingView();
  MovieListingView(this.movieList);
  final MovieCatalog movieList;

  //bool theExpanded = false;

  List<MovieCategoryView> generateCategoryList() {
    List<MovieCategoryView> tempList = [];
    List<String> movieCategories = movieList.Categories;
    
    movieCategories.forEach((category) {
      MovieCategoryView categoryView = new MovieCategoryView(
          movieCategoryName: category.toString(),
          movieList: movieList.getMovieCardListByCategory(category));
      tempList.add(categoryView);
    });
    return tempList;
  }
  
}

class _MovieListingView extends State<MovieListingView> {
    Widget build(BuildContext context) {
    // TODO: implement build
    return SingleChildScrollView(
      physics: ScrollPhysics(),
      padding: EdgeInsets.all(5.0),
      child: _buildCategoryListings(),
    );
  }

  
  List<MovieCategoryView> generateCategoryList() {
    List<MovieCategoryView> tempList = [];
    List<String> movieCategories = widget.movieList.Categories;
    int counter = 0;

    movieCategories.forEach((category) {
      MovieCategoryView categoryView = new MovieCategoryView(
          movieCategoryName: category.toString(),
          movieList:
          widget.movieList.getMenuItemCardListByCategory(category),
          isExpanded: false);
      tempList.add(categoryView);
    });
    return tempList;
  }

  Widget _buildCategoryListings() {
    final List<MovieCategoryView> theListings = generateCategoryList();
    return ExpansionPanelList(
      expansionCallback: (panelIndex, isExpanded) {
        setState(() {
          theListings[panelIndex].isExpanded = !isExpanded;
          //widget.theExpanded = !isExpanded;
        });
      },
      children: theListings.map((MovieCategoryView movieCategoryView) {
        return ExpansionPanel(
            canTapOnHeader: true,
            headerBuilder: (BuildContext context, bool isExpanded) {
              return ListTile(
                title: Text(movieCategoryView.movieCategoryName),
              );
            },
            body: Column(
              children: movieCategoryView.movieList,
            ),
            isExpanded: movieCategoryView.isExpanded);
      }).toList(),
    );
  }
}

class MovieCategoryView {
  MovieCategoryView(
      {@required this.movieCategoryName,
        @required this.movieList,
        this.isExpanded});
  String movieCategoryName;
  List<MovieCard> movieList;
  bool isExpanded = false;
  
}

CodePudding user response:

This is happening because whenever the setstate() is called whole widget tree is rebuild and thus when you try changing the isexpandable value ,is gets changed but the function generateCategoryList(); again gets called and generates the previous list again and again.

Widget _buildCategoryListings() {
    final List<MovieCategoryView> theListings = generateCategoryList();
  

To fix this call the generateCategoryList(); once in initState() and remove the line above line.

  • Related