Home > Software design >  ElevatedButton onPressed function executing on its own
ElevatedButton onPressed function executing on its own

Time:08-18

I am building a quiz app which has a homepage that allows you to select the subject you want to be quizzed on and then displays the questions. However, when I run my code, it doesn't display this homepage and instead displays the questions that should come if the last button was pressed. Here are the relevant snippets of my code:

[main.dart]

import 'package:flutter/material.dart';
import './page.dart';
import './s_button.dart';

class _MyAppState extends State<MyApp> {

  List subjects = ["biology", "chemistry", "physics"];

  bool PageIndex = true; 

  String selected_subject = "";

  void changePage(s) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() {
        selected_subject = s;
        PageIndex = false;
      });
    });
  } 

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.pink[100],
        body: PageIndex ? Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Quiz App", style: TextStyle(fontSize: 24)),
              SizedBox(height: 30),
              Text("Select a subject"), 
              SizedBox(height: 40),
              ...subjects.map((sub){
                return SubjectButton(pageHandler: changePage, subject: sub);
              })
            ]
          ),
        ) 
        : QuizPage(selected_subject) 
      )
    );
  }
}

[s_button.dart]

import 'package:flutter/material.dart';

class SubjectButton extends StatelessWidget {

  final Function pageHandler;
  final String subject;

  const SubjectButton({Key? key, required this.pageHandler, required this.subject}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          width: 120, 
          height: 60,
          child: ElevatedButton(
            style: ElevatedButton.styleFrom(
              primary: Colors.pink,
              elevation: 5, 
            ),
            onPressed: pageHandler(subject),
            child: Text(subject) 
          )
        ),
        SizedBox(height: 20)
      ],
    );
  }
}

When I run this however, QuizPage() is displayed with the question for physics, which is the last button as per my initial list. Somehow, my PageIndex is being set to false and my selected_subject is being set to "physics" before I even have a chance to click on the buttons. What is going wrong?

CodePudding user response:

onPressed: pageHandler(subject) means, while building the widget, it will be called.

To call on runtime use

onPressed:()=> pageHandler(subject),

CodePudding user response:

use

 onPressed:()=> pageHandler(subject),

instead of

onPressed: pageHandler(subject),

CodePudding user response:

Check the onPressed line, you're directly executing the function and assigning the return to the onPressed but not binding it.

onPressed: pageHandler(subject),

You may meant to do the following:

onPressed: () => pageHandler(subject),

Like this, it won't get automatically executed at first :)

  • Related