Search code examples
flutterdartvariablesimportboolean

How to access boolean value of one file in another


I am new at flutter and building a project. I have two files naming distractor.dart and layout.dart. In distractor I use images which has a boolean value that keeps changing from true to false back forth for the set run time of the program. what I want to know is when a user presses a button or without a button what I the boolean value of the image used in distractor file. I want to know that value in my layout file. can someone help me resolve or make me understand its working. Thank you.

This is my layout file

import 'package:adhd/distracter.dart';
import 'package:adhd/distracter2.dart';
import 'package:adhd/stimuli.dart';

import 'package:flutter/material.dart';

class Layout extends StatefulWidget {
  const Layout({Key? key}) : super(key: key);

  @override
  State<Layout> createState() => _LayoutState();
}

class _LayoutState extends State<Layout> {
  @override
  Widget build(BuildContext context) {
    final btn = Material(
      elevation: 5,
      borderRadius: BorderRadius.circular(30),
      color: const Color.fromARGB(255, 208, 99, 99),
      child: MaterialButton(
          padding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
          minWidth: MediaQuery.of(context).size.width * 0.3,
          onPressed: () {},
          child: const Text(
            "Go",
            textAlign: TextAlign.center,
            style: TextStyle(
                fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
          )),
    );

    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
        height: MediaQuery.of(context).size.height,
        width: double.infinity,
        decoration: const BoxDecoration(
          image: DecorationImage(
              image: AssetImage("assets/images/bg.jpg"), fit: BoxFit.cover),
        ),
        child: Column(children: [
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Distracter(showImage: false,),
              const SizedBox(
                height: 110,
              ),
              Distracter2(),
            ],
          ),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          const Stimuli(),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Distracter2(),
              const SizedBox(
                height: 110,
              ),
            ],
          ),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          btn
        ]),
      ),
    );
  }
}`.

this is my distractor file

import 'package:flutter/material.dart';

class Distracter extends StatefulWidget {
  bool showImage = false;
  Distracter({ required this.showImage,
    Key? key,
  }) : super(key: key);

  @override
  State<Distracter> createState() => _DistracterState();
}

class _DistracterState extends State<Distracter>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
      reverseDuration: const Duration(seconds: 4),
    )
      ..addListener(() {
        if (controller.status == AnimationStatus.completed) {
          controller.reverse();
        }
        if (controller.status == AnimationStatus.dismissed) {
          controller.forward();
        }
        setState(() {});
      })
      ..forward();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    showD1() {
      if (controller.status == AnimationStatus.forward) {
        widget.showImage = true;
      }
      if (controller.status == AnimationStatus.reverse) {
        widget.showImage = false;
      }
      if (widget.showImage) {
        return SizedBox(
            height: 110,
            child: Image.asset(
              "assets/images/character_robot_attack0.png",
              fit: BoxFit.contain,
            ));
      } else {
        return const SizedBox(
          height: 110,
        );
      }
    }

    return showD1();
  }
}

Solution

  • You can keep track boolean value in parent class (Layout file) and use a callback in your child class to change its value. This is usually called Lifting state up. It's quite simple solution for this problem. The other solutions including state management using different packages available on pub.dev, one of them recommended by Flutter team is provider package. I am mentioning out of the box solution here.

    layout.dart

    class Layout extends StatefulWidget {
      const Layout({Key? key}) : super(key: key);
    
      @override
      State<Layout> createState() => _LayoutState();
    }
    
    class _LayoutState extends State<Layout> {
    
    // initiate your value here, use `setState` if you wish to rebuild the class.
    
    bool showImage = false;
    void setShowImage(bool value) => showImage = value;
    
    
      @override
      Widget build(BuildContext context) {
       /// code retracted
    

    Now pass these values into distractor file.

    class Distracter extends StatefulWidget {
      final bool showImage;
      final VoidCallback setShowImage;
      Distracter({ 
    required this.showImage,
    required this.setShowImage,
        Key? key,
      }) : super(key: key);
    
      @override
      State<Distracter> createState() => _DistracterState();
    }
    
    class _DistracterState extends State<Distracter>
        with SingleTickerProviderStateMixin {
      late AnimationController controller;
    
      @override
      void initState() {
        super.initState();
        controller = AnimationController(
          vsync: this,
          duration: const Duration(seconds: 2),
          reverseDuration: const Duration(seconds: 4),
        )
          ..addListener(() {
            if (controller.status == AnimationStatus.completed) {
              controller.reverse();
            }
            if (controller.status == AnimationStatus.dismissed) {
              controller.forward();
            }
            setState(() {});
          })
          ..forward();
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        showD1() {
          if (controller.status == AnimationStatus.forward) {
            widget.setShowImage(true);
          }
          if (controller.status == AnimationStatus.reverse) {
            widget.setshowImage(false);
          }
          if (widget.showImage) {
            return SizedBox(
                height: 110,
                child: Image.asset(
                  "assets/images/character_robot_attack0.png",
                  fit: BoxFit.contain,
                ));
          } else {
            return const SizedBox(
              height: 110,
            );
          }
        }
    
        return showD1();
      }
    }