Come aggiornare lo schermo in flutter

Aug 24 2020

Ho avuto un problema di sbattimento. Voglio provare ad aggiornare il mio schermo dopo

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

nel mio selettore di categoria è stato chiamato. Ho provato a farlo in modo da avere una schermata principale che ha la funzione per il mio selettore di categoria e quindi mi piacerebbe avere la schermata / widget corrente come funzione. Quindi potrei cambiare lo schermo / widget sotto il mio selettore semplicemente cambiando la funzione. Non riesco a trovare un modo per aggiornare la pagina / il corpo della schermata principale dopo aver modificato la funzione (widget sotto il selettore di categoria)

La mia schermata principale:

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
        ],
      ),
    );
  }
}

Il mio selettore di categoria:

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
                  )
                )
            ),
              ),
          );
        }

        )
    );
  }
}

Il file appData.dart in cui si trovano widgetScreenBuilder, screenWidgets e currentScreen:

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

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

Sono nuovo nello sviluppo di app, dart e flutter, quindi qualsiasi aiuto sarebbe apprezzato! Grazie <3

Risposte

1 AhmedElsayed Aug 23 2020 at 23:22

Non riesco a capire bene la tua domanda, ma penso che dovresti provare didChangeDependencies Controllalo: https://api.flutter.dev/flutter/widgets/State/didChangeDependencies.html

Abbas Aug 24 2020 at 00:36

cambia la tua classe MainScreen in questo:

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()
      );
    }
  }

e cambia la tua classe CategorySelector in questo:

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
          ],
        );
      }
    }

Il tuo codice ora funziona correttamente :)

setState () può apportare modifiche solo nella propria classe.