I'm learning Flutter right now, trying to code a simple calculator. I am building rows using this code:
Row( // creates row
mainAxisAlignment: MainAxisAlignment.spaceEvenly, //row is spaced evenly
children: <Widget>[
_button("4", _number("4")), //calls _button widget passing String 4 and function _number, which passes string 4 also
_button("5", _number("5")), //button with value 5
_button("6", _number("6")), //button with value 6
_button("-", _min("null")) //button for subtraction
],
),
my _button widget looks like this:
Widget _button(String number, Function() f(String number)){ //parameters: the button value as String and the function with the value as String
return MaterialButton(
height: buttonHeight,
minWidth: buttonHeight,
child: Text(number,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 48.0)),
textColor: Colors.black,
color: Colors.grey[100],
onPressed: f, //function is called
);
}
Now I want to pass the String number to the Function f, so when the function _number is called, it takes the String number and pastes it onto the display:
void _number(String number){
setState(() {
display=display + number ;
});
}
It does not work, I tried to solve it, but was not successful. Does anyone have an idea?
Thanks!
you have to change this:
Widget _button(String number, Function() f(String number)){ //parameters: the button value as String and the function with the value as String
return MaterialButton(
height: buttonHeight,
minWidth: buttonHeight,
child: Text(number,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 48.0)),
textColor: Colors.black,
color: Colors.grey[100],
onPressed: f, //function is called
);
for this:
Widget _button(String number, Function(String number) f){ //parameters: the button value as String and the function with the value as String
return MaterialButton(
height: buttonHeight,
minWidth: buttonHeight,
child: Text(number,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 48.0)),
textColor: Colors.black,
color: Colors.grey[100],
onPressed: () {
f(number); // function is called
},
);
The main change is that the parameters go inside Function(String param1, String param2) nameFunction which in your case would be Function(String number) f
Related
Here is my code
Container(
child: Positioned(
left: offset.dx,
top: offset.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
offset = Offset(offset.dx + details.delta.dx, offset.dy + details.delta.dy);
print('offset $offset');
});
},
child: Text(_controller.text, textAlign: TextAlign.center, maxLines: 3,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0, color: colorrr)),),
),
)
The easiest way would be for you to put the fontSize in the State of your Widget, and update it from a button or tap somewhere.
Essentially, just like you update the offset, you can update a state variable named fontSize and use it in your TextStyle.
For resize text you may use
dependencies:
auto_size_text: ^3.0.0
import dart code:
import 'package:auto_size_text/auto_size_text.dart';
GestureDetector ontap inside use that code :
onTap: () {
child: AutoSizeText(
'This string will be automatically resized to fit in two lines.',
style: TextStyle(fontSize: 30),
maxLines: 2,
);
Hope you will get solution .
Also to know about package: https://pub.dev/packages/auto_size_text/install
I'm new on flutter, and would like to know how can I apply the onSaved method on my drpdownList.
Please Help!
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*.3,
child: Text('Départ:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
),
Container(
width: MediaQuery.of(context).size.width*.5,
child: _fieldDropDown(_citiesdept, 0, 'depart'),
// onSaved: (value) => _citiesdept = value,
)
],
),
Will this solve your question?
if you want a callback to your widget you need to:
change
_fieldDropDown(List theList, int resultPosition, var dbField) {
// to
_fieldDropDown(List theList, int resultPosition, var dbField, void Function(dynamic newValue) callback) {
make the call when required in the dropDown...
setState(() {
this.resultsList[resultPosition] = newValue;
// HERE is the callback:
callback(newValue);
state.didChange(newValue);
print(
'The List result = ' + this.resultsList[resultPosition]);
//write newValue to a database field, which can be used in the override init to set the field originally
});
and use it as you wish, for example ...
Container(
width: MediaQuery.of(context).size.width*.5,
child: _fieldDropDown(_citiesdept, 0, 'depart'),
callback: (value) => print(value),
I have recently started exploring flutter few days back. I have created a list which has some rows.
Some rows has the Child data.
Right now screen has customised button on the top.
final topAppBar = AppBar(
elevation: 0.1,
backgroundColor: Color.fromRGBO(0, 113, 188, 1.0),
title: Text("RESOURCES", style: TextStyle(
color: Colors.white,
fontFamily: 'Raleway-ExtraBold',
fontWeight: FontWeight.w900,
fontSize: 20.0,
),),
leading: IconButton(
icon: new Image.asset('assets/images/settings.png'),
),
);
When user clicks on those rows I want to just refresh the list with child data and push effect with updating “back button” on the top.
The below code is able to navigate the screen with push effect but how can we maintain the state of application with data as well as back button.
ListTile makeResourcesListTile(Resources resources) => ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0.0),
title: Text(
resources.title,
style: TextStyle(
color: Colors.white,
fontSize: 14.0,
fontWeight: FontWeight.bold,
fontFamily: "Raleway-Bold",
),
),
trailing:
Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 30.0),
onTap: () {
Navigator.pushNamed(context, ‘/listScreen’);
},
);
Please suggest. Thank you in advance
I think you should have a look at: Passing data between screens in Flutter
Is this what you are looking for?
LE:
If you just want to change data source for the list and add a back button, please try this code:
class MyHomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
bool showDetails = false;
String title = 'Resources';
List<Resource> resources = [
new Resource('1', 'one', null),
new Resource('2', 'two', [new Resource('Child', 'Child', null)]),
new Resource('3', 'three', null),
new Resource('4', 'four', [
new Resource('Child', 'Child', null),
new Resource('Child', 'Child', null)
]),
new Resource('5', 'five', null)
];
List<Resource> currentSource;
#override
Widget build(BuildContext context) {
if (!showDetails) {
currentSource = resources;
}
Widget showResourcesList() {
return new ListView.builder(
itemCount: currentSource.length,
itemBuilder: (BuildContext context, int index) {
return new ListTile(
title: Center(
child: Text(currentSource[index].name),
),
onTap: () {
setState(() {
if (currentSource[index].children != null) {
title = 'Children for ' + currentSource[index].name;
currentSource = resources[index].children;
showDetails = true;
}
});
});
});
}
Widget showBackButton() {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
setState(() {
showDetails = false;
currentSource = resources;
title = 'Resources';
});
},
);
}
Widget showSettingsButton() {
return IconButton(
icon: Icon(Icons.settings),
onPressed: () {},
);
}
return Scaffold(
appBar: AppBar(
elevation: 0.1,
backgroundColor: Color.fromRGBO(0, 113, 188, 1.0),
title: Text(
title,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 20.0,
),
),
leading: showDetails ? showBackButton() : showSettingsButton(),
),
body: showResourcesList(),
);
}
}
class Resource {
String name;
String description;
List<Resource> children;
Resource(this.name, this.description, this.children);
}
I used a bool variable (showDetails) which represents the app state and I change the data source when tapping on a listTile.
UI stutters whenever CupertinoDatePicker is rotated due to using the picker in a FormField and calling formFieldState.didChange() on the picker's onDateTimeChanged
I'm trying to use Cupertino input fields in my app.
I've followed the steps in the Flutter Gallery to use CupertinoDatePicker. However, I'm wrapping the input fields inside a Form for validation.
This works, as I was able to tie the state of the picker to the FormFieldState. However, UI performance is abysmal. Every time the picker is rotated, I experience stutters. This is due to continuous call of state.didChange() on onDateTimeChanged
I tried calling state.didChange() only after the modal popup was dismissed, and it got rid of the stutters. But I want the state of the FormField to update as the user spins the picker.
Here's my code snippet.
Widget _getCupertinoDateTimeFormField(FormFieldState<DateTime> state) {
return GestureDetector(
onTap: () async {
await showCupertinoModalPopup<void>(
context: state.context,
builder: (BuildContext context) {
return _buildBottomPicker(
CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: state.value?? DateTime.now(),
onDateTimeChanged: (DateTime newDateTime) {
state.didChange(newDateTime);
},
)
);
},
);
},
child: cupertinoDecoration(state, description,
Text(
_formatUI(state.value),
style: const TextStyle(color: CupertinoColors.inactiveGray),
),
),
);
}
Widget _buildBottomPicker(Widget picker) {
return Container(
height: _kPickerSheetHeight,
padding: const EdgeInsets.only(top: 6.0),
color: CupertinoColors.white,
child: DefaultTextStyle(
style: const TextStyle(
color: CupertinoColors.black,
fontSize: 22.0,
),
child: GestureDetector(
// Blocks taps from propagating to the modal sheet and popping.
onTap: () {},
child: SafeArea(
top: false,
child: picker,
),
),
),
);
}
Widget cupertinoDecoration <T> (FormFieldState<T> state, String description, Widget field) {
bool isError = state.errorText != null;
Widget label = Padding(
padding: EdgeInsets.symmetric(vertical: 1.0),
child: Text(
description,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14.0,
color: CupertinoColors.black,
),
),
);
List<Widget> fieldWidgets = [label, field];
if (isError) {
// add our error message
fieldWidgets.add(Text(
state.errorText,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: CupertinoColors.destructiveRed,
fontSize: 12.0,
),
));
}
return Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
border: Border(
bottom: BorderSide(
color: CupertinoColors.inactiveGray, width: 0.0),
),
),
child: Padding(
padding:
const EdgeInsets.all(6.0),
child: SafeArea(
top: false,
bottom: false,
child: DefaultTextStyle(
style: const TextStyle(
letterSpacing: -0.24,
fontSize: 17.0,
color: CupertinoColors.black,
),
child: Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: fieldWidgets,
),
),
),
),
),
);
}
Am I out of luck here? Are we not supposed to link the state of the picker to the state of the FormField?
Thanks in advance!
I have this code from a stateful widget which looks like
static String code = '+1';
String phone;
String finalphone = '$code' + '$phone'; =>this declaration brings an error
that 'Only static members can be accessed in initializers'
How am I supposed to bring the two variables together so that i have something that looks like +1535465345 i am collecting user information
//the widget
Widget form() {
return Form(
key: _formKey,
child: TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0.0),
),
style: TextStyle(
letterSpacing: 2.0,
fontSize: 19.0,
fontWeight: FontWeight.bold,
color: Colors.black87),
onSaved: (value) => phone = value, //the (value) here is a
//string which is
//assigned
//to phone variable declared at the top
),
),
);
}
also making the phone variable static and printing out the concatenated string brings out +1null
Instead of having a field, you can have a getter like
String get finalphone => '$code' + '$phone';
Refer this answer
You need to specify the class to access static members
String finalphone = '${MyClass.code}$phone';
sure it will bring an error you use the phone variable before give it a value so it will fire null reference exception .
whatever here is a complete fix hope it will work :
static String code = '+1';
String phone;
String finalphone = "";
//the widget
Widget form() {
return Form(
key: _formKey,
child: TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0.0),
),
style: TextStyle(
letterSpacing: 2.0,
fontSize: 19.0,
fontWeight: FontWeight.bold,
color: Colors.black87),
onSaved: (value) {phone = value; finalphone = '$code' + '$phone'; }
),
),
);
you may need to use setState to asign value and rebuild the view .