I have a SwitchListTile in my App that determine the text that should be written on another button based on its value. Everything is working fine except for one thing which is that the first time you open the app, the initial text on the button will be nothing '' just as it was declared first time until I switch the SwitchListTile for the first time. So I want to know how to make the text appear from the moment you enter this page.
This is my code:
static String buttonText='';
SwitchListTile(
title: const Text('Enable Bluetooth'),
value: _bluetoothState.isEnabled,
onChanged: (bool value) {
// Do the request and update with the true value then
future() async {
// async lambda seems to not working
if (value) {
await FlutterBluetoothSerial.instance.requestEnable();
setState(() {buttonText = "Press to start collection" ; });
} else {
await FlutterBluetoothSerial.instance.requestDisable();
setState(() {buttonText = "Please enable bluetooth in your device" ; });
}
}
future().then((_) {
setState(() {});
});
},
),
.......................
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
padding: const EdgeInsets.symmetric(horizontal: 30, vertical:40),
textStyle:
const TextStyle(fontSize: 30, fontWeight: FontWeight.bold)),
onPressed: () {
if(_bluetoothState.isEnabled){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const BluetoothConnectionTask()),
);
}
},
child: Text(
buttonText,
style: TextStyle(fontSize: 28,color: Colors.black, letterSpacing: 2.0),
),
),
Please update the Text widget set in your elevated button as below.
Text(
_bluetoothState.isEnabled ? "Press to start collection" : "Please enable bluetooth in your device",
style: TextStyle(fontSize: 28,color: Colors.black, letterSpacing: 2.0),
)
And remove
setState(() {buttonText = "Press to start collection" ; });
setState(() {buttonText = "Please enable bluetooth in your device" ; });
from the onChanged method.
It is not working from first time because, onChanged method will get call when you interact with the SwitchListTile.
If still it's not working, Please let me know with the issue.
Related
I have a screen that I'd put all body in an Obx . I have a Row like bellow
Row(
mainAxisSize: MainAxisSize.min,
children: [
Visibility(
visible: !lastController.posts[i].isDownloaded,
child: GestureDetector(
onTap: () async {
lastController.isDownloading.value = true;
await lastController.setPostIsDownloading(i);
await lastController.Download(i);
await lastController.setPostIsDownloading(i);
lastController.isDownloading.value = false;
},
child: lastController.isDownloading.value?
lastController.posts[i].isDownloading?
SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
backgroundColor: Colors.white,
value:lastController.percentage.value,
),
)
: const Icon(
FontAwesome.download,
color: Colors.white,
)
: const Icon(
FontAwesome.download,
color: Colors.white,
),
),
),
const SizedBox(
width: 10.0,
),
Visibility(
.....
),
],
)
and my Controller is like bellow
class LastMonasebatController extends GetxController {
RxList<Posts> posts = <Posts>[].obs;
Future<void> setPostIsDownloading(int id) async {
posts[id].isDownloading = !posts[id].isDownloading;
posts.refresh();
}
Future<void> Download(int id) async {
........
posts[id].isDownloaded = true;
posts.refresh();
}
}
When I tap on GestureDetector the post downloading until end but the icon does not change and after downloading complete when I hot reload the controller icon disappeared because post.isDownloaded is false . This is not change UI Automatically . What is the problem ?
I want Getx to change the UI automatically
RxList needs a manual update when its elements changes, so it updates on Obx, you need to call refresh() on it like this:
Future<void> Download(int id) async {
........
posts[id].isDownloaded = true;
shabs.refresh();
posts.refresh(); // add this
}
this will tell Obx that the RxList is the same object, but its inside elements did change to update.
and this is an assume, but in your code, there are two checks over isDownloading,
// ...
child: lastController.isDownloading.value?
lastController.posts[i].isDownloading?
// ...
maybe you need to check only over the ones that belongs to the posts[i]:
// ...
child: lastController.posts[i].isDownloading?
// ...
I have this BMI Calculator and I want that the Height can not be under 100 (cm). For that I created a TextFormField which looks like the following:
TextFormField(
onFieldSubmitted: (value) {
setState((){
_heighController.text= value;
if (int.parse(value) >= 100) {
value = "100";
}
value=_heighController.text;
});
},
inputFormatters: [
LengthLimitingTextInputFormatter(3),
FilteringTextInputFormatter.allow(RegExp(r'^[1-9][0-9]*')),
],
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
style: const TextStyle(fontSize: 16, color: Colors.white),
controller: _heighController,
cursorColor: Colors.white,
decoration: InputDecoration(hintText: "in cm", hintStyle: TextStyle(color: Colors.white)),
),
as you can see, I already tried to add onFieldSubmitted, but this doesn't work out like I planned. When I write 90 e.g., it accepts 90 when I press the "enter" button on my keyboard. But when I update the state for this widget with my Plus or minus button (see picture below) it goes to 100 automatically. I want that it goes to 100 every time I leave the "editing option" from this field and the input is below 100. How do I realize that?
You should change the value of the _heighController on your "onFieldSubmitted" function, like this:
onFieldSubmitted: (value) {
setState((){
if (int.parse(value) <= 100) {
value = "100";
}
_heighController.text= value;
});
},
Your error was to attribute the value to your controller before checking the validity.
And after, you set the value of your controller to the parameter of the function, which is pointless in this case.
I created a map called "records", the keys of this map are taken from the user when presed on 'save' botton, and the values are from the time counter that I have in my code.
But the problem is when I create a ListView.builder to export this map indexes to cards, it gave me Null values in each card index !!!
How can I show the real value instead of Null ?!!
Here is my code:
var _item;
List listCount = [];
Map<String, dynamic> records = {};
String name;
createAlertDialog(buildContext, context) {
TextEditingController controller;
return showDialog(
context: context,
// barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: Text(
'Type record name',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.0),
),
content: TextField(
controller: controller,
onChanged: (value) {
name = value;
}),
actions: [
MaterialButton(
elevation: 5.0,
child: Text('Save'),
onPressed: () {
listCount.add(_item);
print(_item);
records[name] = _item;
print(records);
Navigator.pop(context);
},
),
MaterialButton(
elevation: 5.0,
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
],
);
},
);
}
The variable _item is taking it's value from another site, see this:
StreamBuilder<int>(
stream: _stopWatchTimer2.rawTime,
initialData: 0,
builder: (context, snap) {
final value = snap.data;
final displayTime = StopWatchTimer.getDisplayTime(
value,
hours: _isHours2);
_item = displayTime;
return Padding(
padding: EdgeInsets.all(5.0),
child: Text(displayTime,
style: TextStyle(
fontSize: 30.0, color: Colors.white)),
);
},
),
And here where I create the ListView.builder:
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: records.length,
itemBuilder: (context, index) {
return MyCard(
colour: Colors.cyanAccent,
maker: Container(
width: 250.0,
height: 75.0,
child: Text(
'${records[index]}',
style: TextStyle(fontSize: 25.0),
textAlign: TextAlign.center,
),
),
);
},
),
The image in the link is a screen shot from my app.
Image
Looking at the _item variable which is initially null. You are not assigning any value to it. Please check your code. You are assigning a null value to your records because _item has not been given any value.
onChanged: (value){
_item = value;
}
you are not giving any value to the _item variable, I'm assuming you wanted to assign the value in the onChanged event like this:
onChanged: (value) {
_item = value;
}
or maybe you wanted to add the name to the list instead?
If I am understanding correctly, you have stored the item values into the records based on name variable in Save button onPressed event. But you are getting the record through the ListView index values. So, there is no record found in the records collection based on that index. So it returns null value.
Provide the index to store the item in the Save button instead of name. Or check the record based on name inside the ListView builder instead of index.
I'm using the flutter package: https://pub.dev/packages/intro_slider and once the intro has already been viewed the first time the user has logged, I don't want the intro to show on subsequent app opens. There is a visual error where the intro briefly appears before switching to the main app on the subsequent opens, so I tried to use FutureBuilder, but I'm quite inexperienced.
Here is where the widget is being built:
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: restore(),
builder: (BuildContext context, snapshot){
return new IntroSlider(
// List slides
slides: this.slides,
// Skip button
renderSkipBtn: this.renderSkipBtn(),
onSkipPress: this.onSkipPress,
highlightColorSkipBtn: Color(0xff000000),
// Next, Done button
onDonePress: this.onDonePress,
renderNextBtn: this.renderNextBtn(),
renderDoneBtn: this.renderDoneBtn(),
highlightColorDoneBtn: Color(0xff000000),
// Dot indicator
colorDot: Colors.white10,
colorActiveDot: Colors.greenAccent,
sizeDot: 8.0,
);
}
);
}
}
Here is my restore function:
Future<String> restore() async {
final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
setState(() {
yn = (sharedPrefs.getBool('yn') ?? false);
});
if (yn){
Navigator.pushReplacement(context, new MaterialPageRoute(
builder: (context) => SplashScreen()
));
}else{
await sharedPrefs.setBool('yn', true);
}
}
And here's my initState if it matters:
void initState() {
super.initState();
restore();
slides.add(
new Slide(
title: "Hail",
styleTitle:
TextStyle(color: Colors.white, fontSize: 30.0, fontFamily: 'Courier'),
description: "Allow miles wound place the leave had. To sitting subject no improve studied limited",
styleDescription:
TextStyle(color: Colors.white, fontSize: 20.0, fontFamily: 'Mono'),
pathImage: "assets/totoro.png",
backgroundColor: Colors.black,
),
);
}
The yn variable is just to check if it is the user's first time opening the app. Thanks in advance!!
I have two radio button with value 50 and 100. What I want to do is display the value of active radio button every time I pressed the proceed button.
int selectedRadio;
#override
void initState(){
super.initState();
selectedRadio = 0;
}
void setSelectedRadio(int val){
setState(() {
selectedRadio = val;
});
}
void buttonpressed(){
print(selectedRadio);
}
children: <Widget>[
Text("4 Wheels(100)"),
Radio(
value: 100,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged:(val) {
setSelectedRadio(val);
},
),
Text("2 Wheels(50)"),
Radio(
value: 50,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged:(val) {
setSelectedRadio(val);
},
),
RaisedButton(
onPressed: buttonpressed,
child: new Text(
"print radio button value",
),
),
]
The code you posted works fine.
To solve your problem try to do these things:
Check if you're not setting some value to selectedRadio inside
build()
In your project directory try running flutter clean
Instead of using hot-reload restart / reinstall the app