如何使用 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的无限列表(表示层中的列表长度不变)

使用flutter_bloc提交时如何验证表单?

如何使用flutter bloc模式通过分页加载数据列表?

使用 bloc 时如何替换 Flutter 中的 transformEvents?

如何在flutter中重建所有网格项?

如何在集成测试中模拟 BLoC