我的目标是实现Listview的更新。我对我的代码有疑问。但是我必须先说一下我的问题。我使用setState(),但我不明白为什么该功能不起作用,我意识到使用了Stateless小部件。
我使用了这段代码
class _ListItem extends StatelessWidget {
_ListItem({this.bgName, this.name, this.detail});
// final int index;
final String bgName;
final String name;
final String detail;
@override
Widget build(BuildContext context) {
return Container(
height: 180.0,
margin: const EdgeInsets.symmetric(
vertical: 1.0,
),
child: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(bgName),
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.45), BlendMode.darken),
fit: BoxFit.cover,
alignment: Alignment.center),
),
child: new SizedBox.expand(
child: Container(
alignment: Alignment.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(
name,
style: new TextStyle(fontSize: 29.0, color: Colors.white),
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new Text(
detail,
style:
new TextStyle(fontSize: 16.0, color: Colors.white),
),
)
],
),
),
),
),
],
),
);
}
}
最近,我将_ListItem类更改为Stateful Widget
我使用了这段代码
class ListItem extends StatefulWidget {
@override
_ListItem createState() => _ListItem();
}
class _ListItem extends State<ListItem> {
_ListItem({this.bgName, this.name, this.detail});
// final int index;
final String bgName;
final String name;
final String detail;
@override
Widget build(BuildContext context) {
return Container(
height: 180.0,
margin: const EdgeInsets.symmetric(
vertical: 1.0,
),
child: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(bgName),
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.45), BlendMode.darken),
fit: BoxFit.cover,
alignment: Alignment.center),
),
child: new SizedBox.expand(
child: Container(
alignment: Alignment.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(
name,
style: new TextStyle(fontSize: 29.0, color: Colors.white),
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new Text(
detail,
style:
new TextStyle(fontSize: 16.0, color: Colors.white),
),
)
],
),
),
),
),
],
),
);
}
}
但是在外面,它给出了空的列表视图。
此刻,我使用了这段代码。
body: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: listItems.length,
itemBuilder: (BuildContext ctxt, int index){
return GestureDetector(
child: listItems[index].widget,
onTap: () {
//some code
}
);
},
)
所有代码
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:ui';
import 'package:samuraigym/my_icons_icons.dart' as custicon;
import 'package:samuraigym/program_training_handler.dart';
class MeasurementsScreen extends StatefulWidget {
@override
_MeasurementsScreenState createState() => _MeasurementsScreenState();
}
class _MeasurementsScreenState extends State<MeasurementsScreen> {
List<_ListItem> listItems;
String lastSelectedValue;
var name = ["Рост", "Вес","Грудь","Плечи","Бицепс"];
var nameItem = ["Рост", "Вес","Грудь","Плечи","Бицепс"];
var indication = ["Введите ваш рост", "Введите ваш вес"];
var indicationItem = ["Введите ваш рост", "Введите ваш вес"];
TextEditingController customcintroller;
void navigationPageProgrammTrainingHandler() {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => ProgrammTrainingHandler()),
);
}
@override
void initState() {
super.initState();
initListItems();
}
Future<String> createAlertDialog(BuildContext context, int indexAl) async{
customcintroller = TextEditingController();
if(indexAl < 2){
String returnVal = await showDialog(context: context, builder: (context){
return AlertDialog(
title: Text(name[indexAl]),
content: TextField(
textDirection: TextDirection.ltr,
controller: customcintroller,
style: TextStyle(
color: Colors.lightGreen[400],
fontSize: 18.5),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 4.0),
labelText: indication[indexAl],
alignLabelWithHint: false,
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
),
actions: <Widget>[
FlatButton(
child: const Text('ОТМЕНА'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: const Text('ОК'),
onPressed: () {
setState(() {
indicationItem[indexAl] = customcintroller.text.toString();
Navigator.of(context).pop();
});
},
),
],
);
});
} else if (indexAl > 1){
navigationPageProgrammTrainingHandler();
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Color(0xff2b2b2b),
appBar: AppBar(
title: Text(
'Замеры',
style: new TextStyle(
color: Colors.white,
),),
leading: IconButton(
icon:Icon(Icons.arrow_back),
color: Colors.white ,
onPressed:() => Navigator.of(context).pop(),
),
),
body: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: listItems.length,
itemBuilder: (BuildContext ctxt, int index){
return GestureDetector(
child: listItems[index].widget,
onTap: () {
createAlertDialog(context, index).then((onValue){
indicationItem[index] = onValue.toString();
});
}
);
},
),
);
}
void initListItems() {
listItems = [
new _ListItem(
bgName: 'assets/images/soso_growth.jpg',
name: nameItem[0],
detail: "Нажми, чтобы добавить свой рост"),
new _ListItem(
bgName: 'assets/images/soso_weight.jpg',
name: nameItem[1],
detail: "Нажми, чтобы добавить свой вес"),
new _ListItem(
bgName: 'assets/images/soso_chest.jpg',
name: nameItem[2],
detail: "PRO-версия"),
new _ListItem(
bgName: 'assets/images/soso_shoulder.jpg',
name: nameItem[3],
detail: "PRO-версия"),
new _ListItem(
bgName: 'assets/images/soso_biceps.jpg',
name: nameItem[4],
detail: "PRO-версия")
];
}
}
class ListItem extends StatefulWidget {
@override
_ListItem createState() => _ListItem();
}
class _ListItem extends State<ListItem> {
_ListItem({this.bgName, this.name, this.detail});
// final int index;
final String bgName;
final String name;
final String detail;
@override
Widget build(BuildContext context) {
return Container(
height: 180.0,
margin: const EdgeInsets.symmetric(
vertical: 1.0,
),
child: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(bgName),
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.45), BlendMode.darken),
fit: BoxFit.cover,
alignment: Alignment.center),
),
child: new SizedBox.expand(
child: Container(
alignment: Alignment.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(
name,
style: new TextStyle(fontSize: 29.0, color: Colors.white),
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new Text(
detail,
style:
new TextStyle(fontSize: 16.0, color: Colors.white),
),
)
],
),
),
),
),
],
),
);
}
}
请帮帮我。几天我无法解决问题))
答案 0 :(得分:1)
如果要在状态小部件中发送数据,则必须在状态类本身而不是状态中进行
class ListItem extends StatefulWidget {
String bgName;
String name;
String detail;
ListItem({Key key, this.bgName, this.name, this.detail}) : super(key: key);
@override
_ListItem createState() => _ListItem();
}
要在状态类中访问它,请执行以下操作:
//somecode
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(widget.bgName),
//some code
要更改有状态窗口小部件中的状态,请在您点击窗口小部件时调用setState方法,例如,添加手势检测器或InkWell以添加点击功能 并在其中调用设置状态。 制作ListItem的列表以在列表视图构建器
中使用它 List<ListItem> items = [ ListItem(bgName: ' the bgName' ,name :'the
name',detail:'details'),
//add another Items here
];
ListView.builder(
itemCount:items.length,
itemBuilder: (context,index)=>items[index];
);
完整示例
class ListItem extends StatefulWidget {
String bgName;
String name;
String detail;
ListItem({Key key, this.bgName, this.name, this.detail}) : super(key: key);
@override
_ListItem createState() => _ListItem();
}
class _ListItem extends State<ListItem> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
print(widget.bgName);
//call setState here;
setState(() {
widget.bgName = 'this item is tapped';
});
},
child: Container(
height: 180.0,
margin: const EdgeInsets.symmetric(
vertical: 1.0,
),
child: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(widget.bgName),
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.45), BlendMode.darken),
fit: BoxFit.cover,
alignment: Alignment.center),
),
child: new SizedBox.expand(
child: Container(
alignment: Alignment.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(
widget.name,
style:
new TextStyle(fontSize: 29.0, color: Colors.white),
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: new Text(
widget.detail,
style: new TextStyle(
fontSize: 16.0, color: Colors.white),
),
)
],
),
),
),
),
],
),
),
);
}
}
List<ListItem> items = [ ListItem(bgName: ' the bgName' ,name :'the
name',detail:'details'),
//add another Items here
];
body: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: listItems.length,
itemBuilder: (BuildContext ctxt, int index){
return
listItems[index]
;
},
)
我希望能对您有所帮助。
答案 1 :(得分:0)
tou可以显示使用数据初始化listItems的代码吗?我们不能那样帮您
答案 2 :(得分:0)
对我来说,解决问题的方法是用唯一键将小部件(您的构建器返回的小部件)包装在一个容器中。
在我的情况下,我正在返回构建器中的无状态小部件,因此这是对我有用的代码。
这是我的listView Builer中的return语句
pxor