SetState does not update immediately - flutter

I'm new to flutter and I'm having a problem here.
I'm developing an application to schedule meals and I wanted that when he got to the widget to confirm the appointments the calendar would appear gray and disabled
Booking Area widget
import 'package:app/widgets/booking/datepicker.dart';
import 'package:app/widgets/booking/pageone.dart';
import 'package:flutter/material.dart';
bool confirmationPage = false;
class BookingArea extends StatefulWidget {
const BookingArea({Key? key}) : super(key: key);
#override
_BookingAreaState createState() => _BookingAreaState();
}
class _BookingAreaState extends State<BookingArea> {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: [
Container(
width: 600,
height: 350,
color: Colors.amber,
child: const PageOne(),
),
Container(
foregroundDecoration: confirmationPage
? const BoxDecoration(
color: Colors.grey,
backgroundBlendMode: BlendMode.saturation,
)
: null,
width: 300,
height: 300,
child: const DatePicker(),
),
],
),
);
}
}
Confirmation Page widget
import 'package:app/widgets/booking/booking_area.dart';
import 'package:flutter/material.dart';
class PageOne extends StatefulWidget {
const PageOne({Key? key}) : super(key: key);
#override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
#override
Widget build(BuildContext context) {
setState(() {
confirmationPage = true;
});
return const Center(
child: Text("Pagina 1"),
);
}
}
what happens is that when I give the setState on PageOne it only applies the state (changes the widget color) when I "restart" the page through routes.
What I wanted was that when he got to page one he would immediately change the color of the calendar
sorry for bad english
Thanks :)

That is because you are only updating your PageOne with this setState((){}) call.
It doesn't rebuild the parent widget.
This would be the quick solution, but I would highly recommend looking for a sophisticated statemanagement solution
import 'package:app/widgets/booking/datepicker.dart';
import 'package:app/widgets/booking/pageone.dart';
import 'package:flutter/material.dart';
class BookingArea extends StatefulWidget {
const BookingArea({Key? key}) : super(key: key);
#override
_BookingAreaState createState() => _BookingAreaState();
}
class _BookingAreaState extends State<BookingArea> {
bool confirmationPage = false;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: [
Container(
width: 600,
height: 350,
color: Colors.amber,
child: PageOne(onInit:() {
setState((){
confirmation = true;
});
}),
),
Container(
foregroundDecoration: confirmationPage
? const BoxDecoration(
color: Colors.grey,
backgroundBlendMode: BlendMode.saturation,
)
: null,
width: 300,
height: 300,
child: const DatePicker(),
),
],
),
);
}
}
import 'package:app/widgets/booking/booking_area.dart';
import 'package:flutter/material.dart';
class PageOne extends StatefulWidget {
const PageOne({Key? key, required this.onInit}) : super(key: key);
final VoidCallback onInit;
#override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
#override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
widget.onInit();
});
}
#override
Widget build(BuildContext context) {
return const Center(
child: Text("Pagina 1"),
);
}
}

Related

The argument type 'Function' can't be assigned to the parameter type 'void Function()?'1

import 'package:flutter/material.dart';
class Answer extend`enter code here`s StatelessWidget {
// const ({Key? key}) : super(key: key);
final Function sel`enter code here`ectHandler ;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.pink,
child: Text('Pink'),
// textColor: Colors.pink,
onPressed:selectHandler,
),
);
}
}
hey guys please help me to solve this i am having issue in this code # onPressed:selectHandler
Use voidcallback
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
const ({Key? key, this.selectHandler}) : super(key: key);
final VoidCallback selectHandler ;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.pink,
child: Text('Pink'),
// textColor: Colors.pink,
onPressed:selectHandler,
),
);
}
}
Use GestureTapCallback. Hope that work for you
import 'package:flutter/material.dart';
class Answer extend StatelessWidget {
// const ({Key? key}) : super(key: key);
final GestureTapCallback selectHandler;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.pink,
child: Text('Pink'),
// textColor: Colors.pink,
onPressed:selectHandler,
),
);
}
}

AnimatedPositioned - how to change position automatically without pressing button

i want to use the animated positioned class to change widget position with the launch of the screen without pressing a button!
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool selected = false;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
color: Colors.blue,
child: const Center(child: Text('Tap me')),
),
),
),
],
),
);
}
}
i tried to change it by using a WidgetsBinding like this :
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
selected = true;
});
print(' widget binding : $selected');
});
it works fine but the problem was that it doesnt excuted once, it keeps running and change the value to true! like this :
I copy/past the code you have shared to see what's going on, and it's working just fine for me. I have this code
import 'package:flutter/material.dart';
void main() async {
return runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
selected = true;
});
print(' widget binding : $selected');
});
}
bool selected = false;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 350,
child: Stack(
children: <Widget>[
AnimatedPositioned(
width: selected ? 200.0 : 50.0,
height: selected ? 50.0 : 200.0,
top: selected ? 50.0 : 150.0,
duration: const Duration(seconds: 2),
curve: Curves.fastOutSlowIn,
child: GestureDetector(
onTap: () {
setState(() {
selected = !selected;
});
},
child: Container(
color: Colors.blue,
child: const Center(child: Text('Tap me')),
),
),
),
],
),
);
}
}
The animation is run only once, when the postFrameCallback is called. The problem must be elsewhere

How to change scaffold colour randomly on clicking separate file's gesturdetector button

I have made two files... one is main.dart and other is homescreen.dart. Homescreen is for scaffold body which is created separately. Now there is a button in home screen for changing colour of scaffold. How to do this?
The main purpose is to know access scaffold from other stateful widget class file...
main.dart
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(child: Scaffold(body: HomeScreen(),)),
);
}
}
homescreen.dart
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
//My query is to PLACE CODE HERE TO CHANGE SCAFFOLD COLOR ON CLICKING
},
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: Center(child: Text('Change Color',)),
),
),
);
}
}
Try this:
main.dart
import 'package:flutter/material.dart';
import 'home.dart';
import 'dart:math' as math;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Color _color = Colors.white;
void changeColor(){
setState(() {
_color = Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(child: Scaffold(
backgroundColor: _color,
body: HomeScreen(changeColor: changeColor,),)),
);
}
}
home.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
VoidCallback? changeColor;
HomeScreen({Key? key, this.changeColor}) : super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: changeColor,
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: const Center(
child: Text(
'Change Color',
),
),
),
),
);
}
}
You can do it like this :
/// EDIT :
I edit it to get the Color random
import 'dart:math' as math;
class _MyAppState extends State<MyApp> {
Color _newColor = Colors.white; // variable with the color you want to change
final rnd = math.Random(); // random
Color getRandomColor() =>
Color(rnd.nextInt(0xffffffff)); // little function to get the color random
void _changeNewColor() { // function that you are going to send to yout HomeScreen
setState(() {
_newColor = getRandomColor();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: HomeScreen(change: _changeNewColor), // function
backgroundColor: _newColor, // here the variable
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({
Key? key,
this.change,
}) : super(key: key);
final Function()? change; // instance and get the funct
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: change,
child: Center(
child: Container(
color: Colors.red,
height: 60,
width: 200,
child: const Center(
child: Text(
'Change Color',
)),
),
),
);
}
}

flutter - texteditingcontroller from another class

i am fairly new to flutter, can anyone help me? pls
I would like that once I click the RawMaterialButton(), what I wrote in the TextField() appears as text in the container() class.
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: chat(),
);
}
}
class chat extends StatefulWidget {
const chat({Key? key}) : super(key: key);
#override
_chatState createState() => _chatState();
}
class _chatState extends State<chat> {
bool changeClass = false;
changeClassValue() {
setState(() {
changeClass = !changeClass;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: changeClass
? container(
text: _textFieldState().textController.text,
)
: textField(
changeClassValue: changeClassValue,
),
);
}
}
class textField extends StatefulWidget {
textField({Key? key, required this.changeClassValue}) : super(key: key);
Function changeClassValue;
#override
_textFieldState createState() => _textFieldState();
}
class _textFieldState extends State<textField> {
final textController = TextEditingController();
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Container(
width: 300.0,
height: 60.0,
color: Colors.red,
child: TextField(
controller: textController,
),
),
RawMaterialButton(
onPressed: () {
setState(() {
widget.changeClassValue();
print(textController.text);
});
},
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
container({Key? key, required this.text}) : super(key: key);
String text;
#override
_containerState createState() => _containerState();
}
class _containerState extends State<container> {
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: double.infinity,
height: 60.0,
color: Colors.grey,
child: Text(widget.text),
),
);
}
}
hope someone can help me.
Thank you :) I write this piece because otherwise it won't let me upload itI write this piece because otherwise it won't let me upload itI write this piece because otherwise it won't let me upload it
You need to update the type of changeClassValue to ValueChanged<String> - now you can pass data between textField and chat states.
import 'dart:math';
import 'package:flutter/material.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: chat(),
);
}
}
class chat extends StatefulWidget {
const chat({Key? key}) : super(key: key);
#override
_chatState createState() => _chatState();
}
class _chatState extends State<chat> {
bool changeClass = false;
String? text;
changeClassValue(String? newText) {
setState(() {
changeClass = !changeClass;
text = newText;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: changeClass
? container(
text: text ?? "",
)
: textField(
changeClassValue: changeClassValue,
),
);
}
}
class textField extends StatefulWidget {
textField({Key? key, required this.changeClassValue}) : super(key: key);
ValueChanged<String> changeClassValue;
#override
_textFieldState createState() => _textFieldState();
}
class _textFieldState extends State<textField> {
final textController = TextEditingController();
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Container(
width: 300.0,
height: 60.0,
color: Colors.red,
child: TextField(
controller: textController,
),
),
RawMaterialButton(
onPressed: () {
widget.changeClassValue(textController.text);
},
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
container({Key? key, required this.text}) : super(key: key);
String text;
#override
_containerState createState() => _containerState();
}
class _containerState extends State<container> {
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: double.infinity,
height: 60.0,
color: Colors.grey,
child: Text(widget.text),
),
);
}
}

Cursor pointing hover animation in Flutter web

I have SVG as an image file where I want to do this cursor hover effect.
I tried onhoverbutton but that does not work here.
I am using flutter_svg package for showing SVG image
Container(
width: double.infinity,
height: 400,
child: SvgPicture.asset('assets/below.svg',
cacheColorFilter: true,
color: const Color(0xff2C66B8)),
)
This is what I want in my web-app
if you run below code in dartpad, you will get idea about how hover works in flutter.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MouseRegion with custom cursor',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: MouseRegionWithCustomCursor(
cursor: const Icon(Icons.refresh, color: Colors.white),
// here you have to replace this with your svg image
child: Container(width: 300, height: 200, color: Colors.blueGrey),
),
);
}
}
// and in this class you can implement your blue line expansion and compression lines
class MouseRegionWithCustomCursor extends HookWidget {
final Widget cursor;
final Widget child;
const MouseRegionWithCustomCursor({
Key? key,
required this.cursor,
required this.child,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final cursorPosition = useState<Offset?>(null);
return MouseRegion(
cursor: SystemMouseCursors.none,
onHover: (event) => cursorPosition.value = event.localPosition,
onExit: (event) => cursorPosition.value = null,
child: Stack(
children: [
child,
if (cursorPosition.value != null)
AnimatedPositioned(
duration: const Duration(),
left: cursorPosition.value?.dx,
top: cursorPosition.value?.dy,
child: cursor,
),
],
),
);
}
}
i know this is not best explanation but you can start with this.