我有一个 dashboard (以网格表示),应该在长按事件中删除项目(使用flutter_bloc),但是会删除最后一个项目而不是选中项目。所有调试打印均显示,该所需元素实际上已从列表中删除,但视图层仍保留该元素。
我的构建功能代码:
Widget build(BuildContext context) {
double pyxelRatio = MediaQuery.of(context).devicePixelRatio;
double width = MediaQuery.of(context).size.width * pyxelRatio;
return BlocProvider(
bloc: _bloc,
child: BlocBuilder<Request, DataState>(
bloc: _bloc,
builder: (context, state) {
if (state is EmptyDataState) {
print("Uninit");
return Center(
child: CircularProgressIndicator(),
);
}
if (state is ErrorDataState) {
print("Error");
return Center(
child: Text('Something went wrong..'),
);
}
if (state is LoadedDataState) {
print("empty: ${state.contracts.isEmpty}");
if (state.contracts.isEmpty) {
return Center(
child: Text('Nothing here!'),
);
} else{
print("items count: ${state.contracts.length}");
print("-------");
for(int i = 0; i < state.contracts.length; i++){
if(state.contracts[i].isFavorite)print("fut:${state.contracts[i].name} id:${state.contracts[i].id}");
}
print("--------");
List<Widget> testList = new List<Widget>();
for(int i = 0; i < state.contracts.length; i++){
if(state.contracts[i].isFavorite) testList.add(
InkResponse(
enableFeedback: true,
onLongPress: (){
showShortToast();
DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
dashBloc.dispatch(new UnfavRequest(state.contracts[i].id));
},
onTap: onTap,
child:DashboardCardWidget(state.contracts[i])
)
);
}
return GridView.count(
crossAxisCount: width >= 900 ? 2 : 1,
padding: const EdgeInsets.all(2.0),
children: testList
);
}
}
})
);
}
full class code和dashboard bloc
看起来像网格会自行重建,但不要重建其图块。 如何使用其所有子部件完全更新网格小部件?
附言:我花了两天时间对其进行修复,请帮助
答案 0 :(得分:2)
我认为您应该使用GridView.builder
构造函数来指定一个构建函数,该构建函数将根据项目列表中的更改而更新,因此,当数据中发生任何更新时,BlocBuilder
将触发该构建函数GridView
内。
我希望这个例子更清楚。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Test(),
);
}
}
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
List<int> testList = List<int>();
@override
void initState() {
for (int i = 0; i < 20; i++) {
testList.add(i);
}
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
floatingActionButton: FloatingActionButton(
//Here we can remove an item from the list and using setState
//or BlocBuilder will rebuild the grid with the new list data
onPressed: () => setState(() {testList.removeLast();})
),
body: GridView.builder(
// You must specify the items count of your grid
itemCount: testList.length,
// You must use the GridDelegate to specify row item count
// and spacing between items
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
childAspectRatio: 1.0,
crossAxisSpacing: 1.0,
mainAxisSpacing: 1.0,
),
// Here you can build your desired widget which will rebuild
// upon changes using setState or BlocBuilder
itemBuilder: (BuildContext context, int index) {
return Text(
testList[index].toString(),
textScaleFactor: 1.3,
);
},
),
);
}
}
答案 1 :(得分:0)
您的代码始终发送int i的最后一个值。
所以不是
for(int i = 0; i < state.contracts.length; i++){
if(state.contracts[i].isFavorite) testList.add(
InkResponse(
enableFeedback: true,
onLongPress: (){
showShortToast();
DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
dashBloc.dispatch(new UnfavRequest(state.contracts[i].id));
},
onTap: onTap,
child:DashboardCardWidget(state.contracts[i])
)
);
做
List<Widget> testList = new List<Widget>();
state.contracts.forEach((contract){
if(contract.isFavorite) testList.add(
InkResponse(
enableFeedback: true,
onLongPress: (){
showShortToast();
DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
dashBloc.dispatch(new UnfavRequest(contract.id));
},
onTap: onTap,
child:DashboardCardWidget(contract)
)
));
答案 2 :(得分:0)
它真的在重建吗?我只是不明白为什么您将State与 BLoC 一起使用。即使使用 State ,也应调用 setState()方法以用新数据更新小部件。 我认为最好的解决方案是尝试从 StatelessWidget 继承您的小部件并在 DashBLOC <中调用 dispatch(new UpdateRequest()); / strong>构造函数。
也请始终牢记有关bloc
的链接,其中有很多示例:
https://felangel.github.io/bloc/#/
答案 3 :(得分:0)
只给孩子一个钥匙
return GridView.builder(
itemCount: children.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(3),
itemBuilder: (context, index) {
return Container(
key: ValueKey(children.length+index),
);
});