如何解决flutter setState 不添加小部件
这是我的代码。当您在上面的字段中输入一个城市然后按加号按钮时,它应该添加一个列表磁贴。但事实并非如此!有一个 listView,其中包含所有列表图块。 listView 应该显示列表中的所有列表图块。 当我按下按钮时,会打印一条消息以指示城市的数量。它显示城市已添加,但屏幕上没有任何变化。 ColorfulBox 是我构建的一个小部件。只是一种装饰。
import 'package:Flutter/material.dart';
import 'package:learner/logic/Weather.dart';
import 'ColorfulBox.dart';
class CitiesScreen extends StatefulWidget{
@override
_CitiesScreenState createState() => _CitiesScreenState();
}
class _CitiesScreenState extends State<CitiesScreen>{
List<Weather> weatherData = List<Weather>();
String cityName;
List<Widget> cities = List<Widget>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 20,horizontal: 10),child: Column(
children: <Widget>[
DecoratedBox(
decoration: Boxdecoration(color: Colors.blueAccent,borderRadius: BorderRadius.circular(10),gradient: LinearGradient(colors: [Colors.blue,Colors.purple]) ),child: ColorfulBox(Padding(
padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),child: ListTile(
title: TextField(onChanged: (value){
cityName = value;
},style: TextStyle(fontSize: 20,color: Colors.white),),trailing: FlatButton(
child: Icon(Icons.add,size: 30,color: Colors.white,onpressed: (){
setState(() {
addCity(cityName);
print(cities.length);
});
},)
),SizedBox(height: 30,Expanded(
child: ListView(
shrinkWrap: true,scrollDirection: Axis.vertical,children: cities,)
],);
}
void addCity(String city){
weatherData.add(Weather(city: city));
Container toBeAddedCity = Container(
margin: const EdgeInsets.symmetric(vertical: 20,child: Text(city,style: TextStyle(fontSize: 22,);
cities.add(ColorfulBox(toBeAddedCity));
}
}
你能帮我解决这个问题吗?我不知道! 是不是因为addCity方法在build方法之外?或者它添加但不显示?
解决方法
您可以只使用 ListView.builder(...)
来创建您的小部件。请不要将小部件存储为状态。
示例:
class CitiesScreen extends StatefulWidget {
@override
_CitiesScreenState createState() => _CitiesScreenState();
}
class _CitiesScreenState extends State<CitiesScreen> {
final TextEditingController _controller = TextEditingController();
final List<Weather> _weatherData = <Weather>[];
final Random _rand = Random();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 20,horizontal: 10),child: Column(
children: <Widget>[
DecoratedBox(
decoration: const BoxDecoration(
color: Colors.blueAccent,borderRadius: BorderRadius.all(Radius.circular(10)),gradient: LinearGradient(
colors: <Color>[Colors.blue,Colors.purple],),child: Container(
//ColorfulBox(
color: Colors.blue,child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),child: ListTile(
title: TextField(
controller: _controller,style: const TextStyle(fontSize: 20,color: Colors.white),trailing: FlatButton(
child: const Icon(
Icons.add,size: 30,color: Colors.white,onPressed: () {
setState(() {
_weatherData.add(Weather(city: _controller.text));
});
_controller.clear();
},const SizedBox(height: 30),Expanded(
child: ListView.builder(
shrinkWrap: true,itemCount: _weatherData.length,itemBuilder: (_,int index) => ListTile(
tileColor: Color.fromARGB(
255,_rand.nextInt(255),title: Text(
_weatherData[index].city,style: const TextStyle(
fontSize: 22,)
],);
}
}
,
首先,获取 TextField 值的一种便捷方法是使用 TextEditingController
,而不是使用变量:
// Create a controller
final TextEditingController _textController = TextEditingController();
// Then use it in your TextField
TextField(
controller: _textController,// ... other lines
trailing: FlatButton(
onPressed: () {
// Use the TextController's value
setState(() {
addCity(_textController.text);
});
// Clear the text after using it
_textController.clear();
},
因为您只更新了 cities
数组的内容,但保留了与 ListView 的子级相同的 cities
数组,所以 Flutter 假设状态没有改变,因此不会更新 UI。有两种方法可以解决这个问题:
- 改变整个列表(不推荐用于大量项目):
// Set new value to the list,instead of just adding items in
cities = List.from(cities)..add(ColorfulBox(toBeAddedCity));
- 使用
ListView.builder()
来跟踪您的列表的长度(在添加/删除项目时会修改)(推荐)
ListView.builder(
itemCount: cities.length,itemBuilder: (context,index) => cities[index]
// ... other lines
工作代码:
import 'package:flutter/material.dart';
import 'package:learner/logic/Weather.dart';
import 'ColorfulBox.dart';
class CitiesScreen extends StatefulWidget {
@override
_CitiesScreenState createState() => _CitiesScreenState();
}
class _CitiesScreenState extends State<CitiesScreen> {
final TextEditingController _textEditingController = TextEditingController();
List<Weather> weatherData = List<Weather>();
String cityName;
List<Widget> cities = List<Widget>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 20,child: Column(
children: <Widget>[
DecoratedBox(
decoration: BoxDecoration(color: Colors.blueAccent,borderRadius: BorderRadius.circular(10),gradient: LinearGradient(
colors: [Colors.blue,Colors.purple])),child: ColorfulBox(Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,horizontal: 0),child: ListTile(
title: TextField(
controller: _textEditingController,style: TextStyle(fontSize: 20,trailing: FlatButton(
child: Icon(Icons.add,onPressed: () {
setState(() {
addCity(_textController.text);
_textController.clear();
print(cities.length);
});
},)
),SizedBox(height: 30,scrollDirection: Axis.vertical,itemCount: cities.length,index) => cities[index],);
}
void addCity(String city) {
weatherData.add(Weather(city: city));
Container toBeAddedCity = Container(
margin: const EdgeInsets.symmetric(vertical: 20,child: Text(city,style: TextStyle(fontSize: 22,);
cities.add(ColorfulBox(toBeAddedCity));
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。