Home > database >  How to update variables of a State class inside of an external Widget?
How to update variables of a State class inside of an external Widget?

Time:09-29

I'm new in flutter, Can someone help me how to access the ss variable or the setState protected method of a State class I created inside of a Widget outside that class. I'm trying to organize codes that's why I extract the Widget out of that State class.

main.dart

import 'package:flutter/material.dart';

import 'screens.dart';

void main() => runApp(const App());

enum ScreenState {
  home,
  login,
  register,
}

class App extends StatefulWidget {
  const App({super.key});

  @override
  State<StatefulWidget> createState() => _AppState();
}

class _AppState extends State<App> {
  ScreenState ss = ScreenState.register;

  @override
  Widget build(BuildContext context) {
    switch (ss) {
      case ScreenState.register:
        return registerPage();
      default:
        return registerPage();
    }
  }
}

screens.dart

import 'package:flutter/material.dart';

import 'components.dart';

Widget registerPage() {
  return MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      brightness: Brightness.dark,
      primaryColor: Colors.blueGrey,
    ),
    home: Scaffold(
      appBar: appHeader(),
      body: registerForm(),
    ),
  );
}

components.dart

import 'package:flutter/material.dart';

PreferredSizeWidget appHeader() {
  return AppBar(
    title: const Text('Register Form'),
    actions: [
      TextButton(
        child: const Padding(
          padding: EdgeInsets.symmetric(horizontal: 10),
          child: Text(
            'Home',
            style: TextStyle(
              color: Colors.white,
              decoration: TextDecoration.underline,
            ),
          ),
        ),
        onPressed: () {/* _AppState.ss = ScreenState.home; */},
      ),
      TextButton(
        child: const Padding(
          padding: EdgeInsets.symmetric(horizontal: 10),
          child: Text(
            'Log In',
            style: TextStyle(
              color: Colors.white,
              decoration: TextDecoration.underline,
            ),
          ),
        ),
        onPressed: () {/* _AppState.ss = ScreenState.login; */},
      ),
    ],
  );
}

Widget registerForm() {
  return SingleChildScrollView(
    child: Center(
      child: Container(
        constraints: const BoxConstraints(
          minWidth: 300,
          maxWidth: 500,
        ),
        padding: const EdgeInsets.symmetric(
          vertical: 40,
          horizontal: 20,
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const Text('Account Information'),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: const InputDecoration(
                labelText: 'Create username',
                hintText: 'Enter username',
                prefixIcon: Icon(Icons.person),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
              validator: (value) {
                return value!.isEmpty ? 'Please create a username' : null;
              },
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.visiblePassword,
              decoration: const InputDecoration(
                labelText: 'Create password',
                hintText: 'Enter password',
                prefixIcon: Icon(Icons.lock),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
              validator: (value) {
                return value!.isEmpty ? 'Please create a password' : null;
              },
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.visiblePassword,
              decoration: const InputDecoration(
                labelText: 'Re-enter password',
                hintText: 'Enter password',
                prefixIcon: Icon(Icons.lock),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
              validator: (value) {
                return value!.isEmpty ? 'Please re-enter password' : null;
              },
            ),
            const SizedBox(
              height: 30,
            ),
            const Text('Personal information'),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: const InputDecoration(
                labelText: 'Last name',
                hintText: 'Enter your last name',
                prefixIcon: Icon(Icons.edit),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
              validator: (value) {
                return value!.isEmpty ? 'Please enter your last name' : null;
              },
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: const InputDecoration(
                labelText: 'First name',
                hintText: 'Enter your first name',
                prefixIcon: Icon(Icons.edit),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
              validator: (value) {
                return value!.isEmpty ? 'Please enter your first name' : null;
              },
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: const InputDecoration(
                labelText: 'Middle name (optional)',
                hintText: 'Enter your middle name',
                prefixIcon: Icon(Icons.edit),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
            ),
            const SizedBox(
              height: 10,
            ),
            TextFormField(
              keyboardType: TextInputType.text,
              decoration: const InputDecoration(
                labelText: 'Suffix (optional)',
                hintText: 'Enter your suffix',
                prefixIcon: Icon(Icons.edit),
                border: OutlineInputBorder(),
              ),
              onChanged: (String value) {},
            ),
          ],
        ),
      ),
    ),
  );
}

I commented out the code that I expect to work but it turns out to be an error. Please teach me on how to fix the error. Thank you so much.

CodePudding user response:

You can change your state to this:

class _AppState extends State<App> {
  ScreenState ss = ScreenState.register;

  @override
  Widget build(BuildContext context) {
    switch (ss) {
      case ScreenState.register:
        return registerPage(changeState);
      default:
        return registerPage(changeState);
    }
  }
  
  void changeState(ScreenState s) {
    setState(() {
      ss = s;
    });
  }
}

Then registerPage like

Widget registerPage(Function(ScreenState) f) {

with

appBar: appHeader(f),

and then appHeader like

PreferredSizeWidget appHeader(Function(ScreenState) f) {

and then this for example:

onPressed: () {f(ScreenState.home);},
  • Related