Home > Software engineering >  Flutter - How to execute a function only once in build method?
Flutter - How to execute a function only once in build method?

Time:12-04

I am trying to get a function to run (render a widget) only once. This is my main build function of the screen. You may ignore most of the code, just see the commented line towards the bottom.

  Widget build(BuildContext context) {
  workoutId = box.get('workoutId');
  
  final arguments = ModalRoute.of(context)!.settings.arguments as Map;
  exerciseName = arguments["exerciseName"];
  exerciseId = arguments["exerciseId"];
  return Scaffold(
    appBar: AppBar(
      leading: IconButton(
          icon: const Icon(
            Icons.arrow_back,
            color: kBlack,
          ),
          onPressed: () {
            Navigator.pop(context);
          }),
      backgroundColor: Colors.transparent,
      title: Text(
        exerciseName,
        style: const TextStyle(
            color: kAppTextColor, fontSize: kAppButtonTextFontSize),
      ),
    ),
    body: Container(

      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Expanded(
            child: Container(
              height: SizeConfig.screenHeight,
              padding: const EdgeInsets.all(0),
              child: ClipRRect(
                child: BackdropFilter(
                  filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
                  child: Container(

                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        _buildInputHeaderRowWidget(),
                        _buildInputRowWidget(),
                        _buildDataTable(),
                        const Padding(
                          padding: EdgeInsets.only(top: 10),
                          child: Divider(
                            height: 10,
                            color: Colors.grey,
                            thickness: 3,
                          ),
                        ),
                        //_buildDataTableForCompletedExercises(),
                        Expanded(
                          child: Container(
                            child: (workoutId != null) 
                                ? _buildDataTableForCompletedExercises() ///THIS NEEDS TO RUN ONLY ONCE
                                : const Text(
                                    'Workout ID is null',
                                    style: TextStyle(
                                        fontSize: kAppButtonTextFontSize),
                                  ),
                          ),
                        ),

How do you achieve this? Do I need to set a flag or something?

CodePudding user response:

Ok, so what you want to do is basically "cache" the result of the function you show, here is what I figure you could do:

First declare a nullable widget, you can call it whatever you want:

Widget? _completedExercises;

then either:

  1. assign it to be the function on init state:
void initState() {
  _completedExercises = _buildDataTableForCompletedExercises();
  super.initState();
}

and then use the widget on the build method:

...
child: (workoutId != null) 
  ? _completedExercises!
  : const Text(
...

or 2. make the function itself cache the value:

Widget _buildDataTableForCompletedExercises() {
  if (_completedExercises == null) {
    _completedExercises = Container(); // here put whatever your function used to be.
  }
  return _completedExercises!;
}

The idea is that the first time the function runs, it will assign the value of _completedExercises and then all subsequent runs will just return the previous value.

  • Related