I am using TextFormField in my code and I have added the suffix icon inside it. I want that the value of textformfield will be assigned to the variable name "city" and the value of the variable city got updated when someone clicks the icon, but it is not happening. please check my code and tell me how to solve this issue. I am using TextFormField in my code and I have added the suffix icon inside it. I want that the value of textformfield will be assigned to the variable name "city" and the value of the variable city got updated when someone clicks the icon. The value of variable city got updated and shows in the terminal when I use the print function. but it does not update the value in the location variable which is getting the value of city variable. location variable is always using the initial value of city variable
import 'package:flutter/material.dart';
import 'model/Weather.dart';
import 'ApiService.dart';
class WeatherData extends StatefulWidget {
WeatherData({Key? key}) : super(key: key);
@override
State<WeatherData> createState() => _WeatherDataState();
}
class _WeatherDataState extends State<WeatherData> {
late Future<WeatherModel> futureWeather;
TextEditingController controller=TextEditingController();
@override
void initState() {
super.initState();
futureWeather = ApiService().getWeather(location: city);
}
String city="Lahore";
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: FutureBuilder<WeatherModel>(
future: futureWeather,
builder: (context, snapshot) {
if (snapshot.data != null) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: Text('Weather App', style: TextStyle(color: Colors.black)),
centerTitle: true,
leading: Icon(Icons.menu, color: Colors.black,),
),
body: SingleChildScrollView(
child: Center(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
children: [
SizedBox(height: 20),
Icon(Icons.wb_sunny_rounded, color: Colors.amber, size: 70,),
SizedBox(height: 10),
Text("${(snapshot.data!.main.temp - 273.15).toStringAsFixed(2)}", style: TextStyle(fontSize: 30)), //current weather
SizedBox(height: 5),
Text(snapshot.data!.name, style: TextStyle(fontSize: 15, color: Colors.black38)), //current location
SizedBox(height: 20),
TextFormField(
controller: controller,
decoration: InputDecoration(
hintText: 'Input City',
labelStyle: TextStyle(
color: Color(0xFF6200EE),
),
suffixIcon: IconButton(
onPressed: () {
setState((){
city=controller.text;
print(city);
});
}, icon: Icon(Icons.search),
),
border: OutlineInputBorder(),
),
),
SizedBox(height: 40),
Text("Additional Information", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87)),
SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Wind", style: TextStyle(fontSize: 14)),
Text(snapshot.data!.wind.speed.toString(), style: TextStyle(fontSize: 14)),
Text("Pressure", style: TextStyle(fontSize: 14)),
Text(snapshot.data!.main.pressure.toString(), style: TextStyle(fontSize: 14)),
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Humidity", style: TextStyle(fontSize: 14)),
Text("20", style: TextStyle(fontSize: 14)),
Text("Feels Like", style: TextStyle(fontSize: 14)),
Text("234", style: TextStyle(fontSize: 14)),
],
),
SizedBox(height: 100),
CircleAvatar(
radius: 30,
backgroundColor: Colors.black12,
child: Icon(Icons.mic_outlined, color: Colors.black, size: 35,),
)
],
),
),
),
),
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
),
));
}
}
CodePudding user response:
setState(() {
city=controller.text;
futureWeather = ApiService().getWeather(location: city);});
CodePudding user response:
The code shows that you are using a future builder. And if you set state the future builder is called again and resets the screen from api. Please extract the text form field to a a separate class and set state from the extracted widget
CodePudding user response:
The concept of using FutureBuilder
is ok on StatefulWidget
.
You need to reassign the future in order to update the future.
while you like to load new city
setState(() {
futureWeather = ApiService().getWeather(location: city);
});
In your case
onPressed: () {
city = controller.text;
futureWeather =
ApiService().getWeather(location: city);
setState(() { });
},