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),
),
);
}
}
Related
I'm quite new to flutter and i'm struggling to get my head around passing variables up the widget tree. I've written a very simple code to demonstrate what i'm trying to achieve and I was hoping someone could please spell it out for me.
I have a parent Stateful widget with a counter in it:
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
int Counter = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
SizedBox(
height: 100,
),
Button(),
],
),
),
);
}
}
then I have another Stateful Widget with the button and bool in it:
class Button extends StatefulWidget {
const Button({Key? key}) : super(key: key);
#override
State<Button> createState() => _ButtonState();
}
class _ButtonState extends State<Button> {
bool buttonPressed = false;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
buttonPressed = !buttonPressed;
print(buttonPressed);
});
},
child: Container(
color: kWhite,
height: 50,
width: 50,
),
);
}
}
I've looked at some of the other answers (using callbacks?) but am struggling to understand how it actually works and how I would implement it into my code
How do I pass the bool variable up the tree to change the counter?
thanks so much and any help would be greatly appreciated
Add the callback function in the Button widget that returns the state of the button pressed.
In Parent widget, add the argument for the callback function which returns the button pressed state.
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
int Counter = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
const SizedBox(
height: 100,
),
Button(isPressed: (isPressed) => print(isPressed)), <-- updated
],
),
),
);
}
}
class Button extends StatefulWidget {
final Function(bool) isPressed; <-- updated
const Button({Key? key, required this.isPressed}) : super(key: key); <-- updated
#override
State<Button> createState() => _ButtonState();
}
class _ButtonState extends State<Button> {
bool buttonPressed = false;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
buttonPressed = !buttonPressed;
print(buttonPressed);
});
widget.isPressed(buttonPressed); <-- updated
},
child: Container(
color: Colors.white,
height: 50,
width: 50,
),
);
}
}
This is how to pass data to parent widget using a callback,
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
int Counter = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
SizedBox(
height: 100,
),
Button(
// here you will get the bool
onBtnPressed: (val) {
print(val);
},
),
],
),
),
);
}
}
class Button extends StatefulWidget {
const Button({required this.onBtnPressed, Key? key}) : super(key: key);
// add this here, this function will act as the callback
final Function onBtnPressed;
#override
State<Button> createState() => _ButtonState();
}
class _ButtonState extends State<Button> {
bool buttonPressed = false;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
setState(() {
buttonPressed = !buttonPressed;
print(buttonPressed);
});
widget.onBtnPressed(buttonPressed);
},
child: Container(
color: kWhite,
height: 50,
width: 50,
),
);
}
}
I would like when I press on the RawMaterialButton, the textField () class changes to the container () class and appears on the screen,
with the code I have now when I press nothing happens ...
can anyone fix it? Thank you.
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;
#override
Widget build(BuildContext context) {
return Scaffold(
body: changeClass ? container() : textField(changeClass: changeClass),
);
}
}
class textField extends StatefulWidget {
textField({Key? key, required this.changeClass}) : super(key: key);
bool changeClass = false;
#override
_textFieldState createState() => _textFieldState();
}
class _textFieldState extends State<textField> {
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Container(
width: 300.0,
height: 60.0,
color: Colors.red,
),
RawMaterialButton(
onPressed: () {
setState(() {
widget.changeClass = true;
});
},
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
const container({Key? key}) : super(key: key);
#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,
),
);
}
}
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 are technically changing a local variable in the _textFieldState, so to solve the problem you have multiple options, one of them is to pass a function that change the state in the _chatState, this code would do so:
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()
: 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> {
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Container(
width: 300.0,
height: 60.0,
color: Colors.red,
),
RawMaterialButton(
onPressed: () {
setState(() {
widget.changeClassValue();
});
},
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
const container({Key? key}) : super(key: key);
#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,
),
);
}
}
where the output would look like:
i am quite a beginner with flutter. i hope someone can help me solve this problem...
I have this code, how can I make that when i press the RawMaterialButton of the textField() class, the changeClass variable of the chat() class changes from textField() to container() ?
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> {
var changeClass = textField();
#override
Widget build(BuildContext context) {
return Scaffold(
body: changeClass,
);
}
}
class textField extends StatefulWidget {
const textField({Key? key}) : super(key: key);
#override
_textFieldState createState() => _textFieldState();
}
class _textFieldState extends State<textField> {
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Container(
width: 300.0,
height: 60.0,
color: Colors.red,
),
RawMaterialButton(
onPressed: () {
// on pressed change this row into container
},
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
const container({Key? key}) : super(key: key);
#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,
),
);
}
}
hope someone can help me
Thank you :)
Define a state variable changeClass in _chatState
In the build method check if the changeClass is true then return the container Widget otherwise return Row widget.
setState the changeClass = trueinonPressed`
_
import 'package:flutter/material.dart';
void main() => runApp(mainApp());
class mainApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const 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;
#override
Widget build(BuildContext context) {
return Scaffold(
body: changeClass
? container()
: textField(
changeClass: changeClass,
callback: () {
setState(() {
changeClass = true;
});
},
),
);
}
}
class textField extends StatefulWidget {
textField({Key? key, required this.changeClass, required this.callback})
: super(key: key);
bool changeClass = false;
VoidCallback callback;
#override
_textFieldState createState() => _textFieldState();
}
class _textFieldState extends State<textField> {
#override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Flexible(
child: Container(
width: 300.0,
height: 60.0,
color: Colors.red,
),
),
RawMaterialButton(
onPressed: widget.callback,
child: Icon(Icons.send),
)
],
),
);
}
}
class container extends StatefulWidget {
const container({Key? key}) : super(key: key);
#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,
),
);
}
}
I want pass the boolean _isSwitched from SetAvailableSwitch class to AvailableScreen class
But actually I can't retrieve the boolean in AvailableScreen class. And as you can see SetAvailableSwitch class is in the Widget build of AvailableScreen class so I don't know how to do that.
AvailableScreen class :
class AvailableScreen extends StatefulWidget
{
const AvailableScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _AvailableScreenState();
}
class _AvailableScreenState extends State<AvailableScreen>
{
void _sendAvailability(BuildContext context)
{
PhpPost().sendAvailability();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: SafeArea(
child: Container(
margin: const EdgeInsets.only(left: 10),
child: Column(
children: [
const SetAvailableSwitch(),
const AvailableSelectGame(),
ElevatedButton(onPressed: () {
_sendAvailability(context);
},
child: const Text("OK"))
],
),
),
),
);
}
}
SetAvailableSwitch class :
class SetAvailableSwitch extends StatefulWidget {
const SetAvailableSwitch({Key? key}) : super(key: key);
#override
_SetAvailableSwitchState createState() => _SetAvailableSwitchState();
}
class _SetAvailableSwitchState extends State<SetAvailableSwitch> {
bool _isSwitched = false;
void _changeSwitch(bool value)
{
setState(() {
if(_isSwitched) {
_isSwitched = false;
}
else{
_isSwitched = true;
}
});
}
#override
Widget build(BuildContext context) {
return Row(
children: [
Text(
Languages.of(context)!.available,
style: const TextStyle(),
),
Switch(value: _isSwitched, onChanged: (value)
{
_changeSwitch(value);
})
],
);
}
}
I want to retrieve the boolean in the function void _sendAvailability(BuildContext context) in AvailableScreen class
An option would be to add a callback method to _AvailableScreenState:
class _AvailableScreenState extends State<AvailableScreen> {
bool _isSwitched = false;
void setIsSwitched(switched) {
setState(() {
_isSwitched = switched;
});
print(_isSwitched);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Container(
margin: const EdgeInsets.only(left: 10),
child: Column(
children: [
SetAvailableSwitch(setIsSwitched),
Which you can call from SetAvailableSwitch:
class SetAvailableSwitch extends StatefulWidget {
final void Function(bool) setSwitched;
const SetAvailableSwitch(this.setSwitched, {Key key}) : super(key: key);
#override
_SetAvailableSwitchState createState() => _SetAvailableSwitchState();
}
class _SetAvailableSwitchState extends State<SetAvailableSwitch> {
bool _isSwitched = false;
void _changeSwitch(bool value) {
setState(() {
if (_isSwitched) {
_isSwitched = false;
} else {
_isSwitched = true;
}
});
widget.setSwitched(_isSwitched);
}
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"),
);
}
}