2

I've gotten a flutter problem. I wanna try to update my screen after

setState(() => {
   widgetScreenBuilder = screenWidgets[currentScreen]
});

in my category selector has been called. I've tried to make it so I have one main screen which has the function for my category selector and then I'd like to have the current screen/widget as a function. Then I could change the screen/widget below my selector just by changing the function. I just can't find a way to refresh the page / the body of the main screen after I've changed the function (widget below category selector)

My main screen:

import 'package:flutter/material.dart';
import 'package:app/widgets/categorySelector.dart';
import 'package:app/data/appData.dart';

class MainScreen extends StatefulWidget {
    @override
    _MainScreen createState() => _MainScreen();
}

class _MainScreen extends State<MainScreen> {
  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColorDark,
      appBar: AppBar(
        backgroundColor: Theme.of(context).primaryColorDark,
        elevation: 0.0,
        title: Center(
          child: Text(
            "Tournaments",
            style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 26.0,
              letterSpacing: 1.1
              )
          ),
        ),
      ),
      body: Column(
        children: <Widget>[
          CategorySelector(),
          widgetScreenBuilder
        ],
      ),
    );
  }
}

My category selector:

import 'package:app/data/appData.dart';
import 'package:flutter/material.dart';

class CategorySelector extends StatefulWidget {
  @override
  _CategorySelectorState createState() => _CategorySelectorState();
}

class _CategorySelectorState extends State<CategorySelector> {
  final List<String> categories = ['All games', 'New game', "New player", "Top players"];
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 75.0,
      color: Theme.of(context).primaryColorDark,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: categories.length,
        itemBuilder: (BuildContext context, int index) {
          return GestureDetector(
            onTap: () {
              if (currentScreen != index) {
                currentScreen = index;
                setState(() => {
                  widgetScreenBuilder = screenWidgets[currentScreen]
                });
              }
            }, 
              child: Center(
                child: Padding(
                padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0),
                child: Text(
                  categories[index],
                  style: TextStyle(
                    fontSize: 24.0,
                    fontWeight: FontWeight.bold,
                    letterSpacing: 1.2,
                    color: index == currentScreen ? Colors.white : Colors.white50
                  )
                )
            ),
              ),
          );
        }

        )
    );
  }
}

The appData.dart file where widgetScreenBuilder, screenWidgets and currentScreen is located:

import 'package:app/widgets/allGames.dart';

int currentScreen = 0;
List screenWidgets = [AllGames(), NewGame()];
var widgetScreenBuilder = screenWidgets[currentScreen];

I'm new to app development, dart and flutter so any help would be appreciated! Thanks <3

paavo_h
  • 21
  • 1
  • 4
  • I didnt read the question properly, but i think you are trying to update the main MainScreen from CategorySelector . If that is the thing, this should answer you: https://stackoverflow.com/questions/51029655/call-method-in-one-stateful-widget-from-another-stateful-widget-flutter – Bensal Aug 23 '20 at 16:15

2 Answers2

1

I can't understand you question well, But i think you should try didChangeDependencies Check it : https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html

ElsayedDev
  • 601
  • 1
  • 8
  • 15
0

change your MainScreen class to this :

class MainScreen extends StatefulWidget {
    @override
    _MainScreen createState() => _MainScreen();
  }
  
  class _MainScreen extends State<MainScreen> {
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        backgroundColor: Theme.of(context).primaryColorDark,
        appBar: AppBar(
          backgroundColor: Theme.of(context).primaryColorDark,
          elevation: 0.0,
          title: Center(
            child: Text("Tournaments",
                style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 26.0,
                    letterSpacing: 1.1)),
          ),
        ),
        body: CategorySelector(), // delete column and just put CategorySelector()
      );
    }
  }

and change your CategorySelector class to this :

class CategorySelector extends StatefulWidget {
      @override
      _CategorySelectorState createState() => _CategorySelectorState();
    }
    
    class _CategorySelectorState extends State<CategorySelector> {
      final List<String> categories = [
        'All games',
        'New game',
        "New player",
        "Top players"
      ];
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            Container(
              height: 75.0,
              color: Theme.of(context).primaryColorDark,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: categories.length,
                itemBuilder: (BuildContext context, int index) {
                  return GestureDetector(
                    onTap: () {
                      if (currentScreen != index) {
                        currentScreen = index;
                        setState(
                          () =>
                              {widgetScreenBuilder = screenWidgets[currentScreen]},
                        );
                      }
                    },
                    child: Center(
                      child: Padding(
                        padding:
                            EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0),
                        child: Text(
                          categories[index],
                          style: TextStyle(
                              fontSize: 24.0,
                              fontWeight: FontWeight.bold,
                              letterSpacing: 1.2,
                              color: index == currentScreen
                                  ? Colors.white
                                  : Colors.white54),
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
            widgetScreenBuilder, // add widgetScreenBuilder here
          ],
        );
      }
    }

Your code is working properly now :)

setState() can only make changes in its own class.

Abbas
  • 208
  • 1
  • 7