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();
}
}
CodePudding user response:
AFAIK you should pass a Callback to Distracter to get the bool.
Distracter(showImage:false, onChanged: (bool value) { /** use the value **/});
//in Distracter
if (controller.status == AnimationStatus.forward) {
widget.showImage = true;
widget.onChanged(true);
}
if (controller.status == AnimationStatus.reverse) {
widget.showImage = false;
widget.onChanged(false);
}
CodePudding user response:
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 way for this problem. This other way is using state management solution like provider
package. I am mentioning simple 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();
}
}
CodePudding user response:
Create a callback function like
class Distracter extends StatefulWidget {
final bool showImage;
final Function(bool) callback;
const Distracter({
this.showImage = false,
required this.callback,
Key? key,
}) : super(key: key);
@override
State<Distracter> createState() => _DistracterState();
}
And
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();
Use it as
Distracter(callback: (value){
print(value);
},