如何使用 bloc flutter 更改单个列表项的状态?
Posted
技术标签:
【中文标题】如何使用 bloc flutter 更改单个列表项的状态?【英文标题】:How to change state of individual list items using bloc flutter? 【发布时间】:2020-10-17 03:29:30 【问题描述】:如何使用 bloc pacakage 在 Flutter 中更改列表项中的小部件。 我应该在整个 ListView.builder 上使用 BlockBuilder 还是侦听器,还是只在单个项目上使用。 如果您分享一个示例或教程,那就太好了。 例如,如果我有一个复选框,我需要在单击它时更改其状态。 这些是我的 Bloc 课程 集团
const String SERVER_FAILURE_MESSAGE = 'Server Failure';
const String CACHE_FAILURE_MESSAGE = 'Cache Failure';
class MarkAttendanceBloc extends Bloc<MarkAttendanceEvent, MarkAttendanceState>
final MarkStudentPresent markStudentPresent;
final MarkStudentAbsent markStudentAbsent;
MarkAttendanceBloc(@required this.markStudentPresent,@required this.markStudentAbsent);
@override
MarkAttendanceState get initialState => MarkedInitial();
@override
Stream<MarkAttendanceState> mapEventToState(MarkAttendanceEvent event) async*
yield MarkedLoading();
if(event is MarkAbsentEvent)
final remotelyReceived = await markStudentAbsent(MarkStudentParams(classId: event.classId, courseId: event.courseId,studentId: event.studentId));
yield* _eitherLoadedOrErrorState(remotelyReceived);
else if(event is MarkPresentEvent)
final remotelyReceived = await markStudentPresent(MarkStudentParams(classId: event.classId, courseId: event.courseId,studentId: event.studentId));
yield* _eitherLoadedOrErrorState(remotelyReceived);
Stream<MarkAttendanceState> _eitherLoadedOrErrorState(
Either<StudentDetailsFacultyFailure,int> failureOrClasses,
) async*
yield failureOrClasses.fold(
(failure) => MarkedError(_mapFailureToMessage(failure)),
(studentId) => Marked(studentId),
);
String _mapFailureToMessage(StudentDetailsFacultyFailure failure)
switch (failure.runtimeType)
case ServerError:
return SERVER_FAILURE_MESSAGE;
default:
return 'No internet';
州
abstract class MarkAttendanceState extends Equatable
const MarkAttendanceState();
class MarkedInitial extends MarkAttendanceState
const MarkedInitial();
@override
List<Object> get props => [];
class MarkedLoading extends MarkAttendanceState
const MarkedLoading();
@override
List<Object> get props => [];
class Marked extends MarkAttendanceState
final int studentId;
Marked(this.studentId);
@override
List<Object> get props => [studentId];
class MarkedError extends MarkAttendanceState
final String errorMessage;
MarkedError(this.errorMessage);
@override
List<Object> get props => [errorMessage];
活动
import 'package:equatable/equatable.dart';
abstract class MarkAttendanceEvent extends Equatable
const MarkAttendanceEvent();
class MarkPresentEvent extends MarkAttendanceEvent
final int studentId;
final int courseId;
final int classId;
MarkPresentEvent(this.studentId, this.courseId, this.classId);
@override
List<Object> get props =>[studentId,courseId,classId];
class MarkAbsentEvent extends MarkAttendanceEvent
final int studentId;
final int courseId;
final int classId;
MarkAbsentEvent(this.studentId, this.courseId, this.classId);
@override
List<Object> get props =>[studentId,courseId,classId];
【问题讨论】:
【参考方案1】:也许现在您已经找到了解决方案,但这就是我设法使用颤振肘部实现相同功能的方式。 此代码是手写的,未经测试,但它应该可以指导您实现目标
1 声明类对象
class ClassItem
int? price;
bool isChecked;
ClassItem(
this.price,
this.isChecked=false,
);
class ClassOverall
List<ClassItem> items;
double? total;
ClassOverall(this.items,this.total);
声明肘类
class OverallCubit extends Cubit<ClassOverall>
OverallCubit(ClassOverallinitialState) : super(initialState);
void checkUncheckCart(int index)
if (!state.items
.elementAt(index).isChecked)
state.items
.elementAt(index).isChecked =
!state.items
.elementAt(index).isChecked;
var t_total = double.tryParse(state.items
.elementAt(index).price!)! * 1;
emit(OverallCubit (state.items,state.total));
else
state.items.elementAt(index).isChecked =
!state.items
.elementAt(index).isChecked;
emit(OverallCubit (state.items,state.total));
calculateTotal();
void calculateTotal()
var tot = 0.0;
for (var tick in state.items)
if (tick.isChecked)
tot = (tick.t_total! + tot);
emit(OverallCubit (state.items,tot));
声明***小部件来保存状态
class TopState extends StatelessWidget
@override
Widget build(BuildContext context)
return BlocProvider(
create: (_) => OverallCubit(ClassOverall(items,0)),//fetch items from your source
child: Home(),
);
声明有状态的小部件并添加一个块构建器
class Home extends StatefulWidget
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<Home>
@override
Widget build(BuildContext context)
return BlocBuilder<OverallCubit, ClassOverall>(
builder: (ctx, state)
return Column(children:[
ListView.builder(
padding: EdgeInsets.all(0.0),
shrinkWrap: true,
itemCount: state.items.length,
itemBuilder: (context, index)
return ListTile(
onTap: ()
ctx
.read<OverallCubit>()
.checkUncheckCart(index);
,
tileColor: state.elementAt(index).isChecked ? Colors.red : Colors.white
title: Text(state.items.elementAt(index).price!),
);
),
Text(state.total.toString),
]);
);
【讨论】:
以上是关于如何使用 bloc flutter 更改单个列表项的状态?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter中带有bloc的无限列表(表示层中的列表长度不变)