我有一个ID为ID的数据列表:
[
{
"id": 1,
"title": "close",
},
{
"id": 2,
"title": "car",
},
我在水平轴的列表视图中显示此列表:
Column(
children: <Widget>[
Container(
height: 50.0,
color: Colors.white,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: _categories.data.length,
itemBuilder: (_, index) {
return Container(
child: InkWell(
onTap: () {
setState(() {
_selectedCat = _categories.data[index].id;
});
},
child: Container(
color: (index + 1) ==
_categories.pagination.currentPage
? Colors.red
: Colors.white,
margin: EdgeInsets.all(8.0),
child: Text(
_categories.data[index].title,
style: TextStyle(
fontSize: 16.0, fontWeight: FontWeight.bold),
),
),
),
);
},
),
),
Expanded(child: CategoryWidget(selectedCat: _selectedCat))
],
),
在CategoryWidget中,我显示与上述数据有关的项目:
class CategoryWidget extends StatefulWidget {
final int id;
const CategoryWidget({@required this.id});
@override
_CategoryWidgetState createState() => _CategoryWidgetState();
}
class _CategoryWidgetState extends State<CategoryWidget> {
Future _future;
@override
void initState() {
_future = HomeProvider().getItems(widget.id); // not triggered
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder<ItemModel>(
future: _futureCategory,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (_, index) {
return Text(snapshot.data.data[index].name);
});
},
),
);
}
}
但是当我用胶带贴在每个水平项目上时:
onTap: () {
setState(() {
_selectedCat = _categories.data[index].id;
});
}
并且设置状态完成,initState
中的CategoryWidget
没有触发?
[initState()
不会在您重建状态时被触发,它只会被触发一次,也就是在加载小部件时,build
方法是在您重建状态时被触发的。
将您的代码更改为此:
@override
Widget build(BuildContext context) {
_future = HomeProvider().getItems(widget.id);
return Container(
child: FutureBuilder<ItemModel>(
future: _futureCategory,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (_, index) {
return Text(snapshot.data.data[index].name);
});
},
),
);
}
}
[State class” docs中明确提到过。
我认为正确的方法是重写State子类中的didUpdateWidget方法。
@override
void initState() {
_getItem();
super.initState();
}
@override
void didUpdateWidget(CategoryWidget oldWidget) {
_getItem();
super.didUpdateWidget(oldWidget);
}
void _getItem() async {
_future = HomeProvider().getItems(widget.id);
}