Advertisement
chayanforyou

flutter_paging_viewmodel_example_2

Jun 19th, 2025
423
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 4.17 KB | None | 0 0
  1. class DoctorListViewModel extends StateNotifier<DoctorPagingState> {
  2.   final DefaultQueryParams _param;
  3.  
  4.   DoctorListViewModel(this._param)
  5.       : super(
  6.           DoctorPagingState(
  7.             pagingState: PagingState(),
  8.           ),
  9.         );
  10.  
  11.   String? _searchTerm;
  12.   bool _isDisposed = false;
  13.  
  14.   @override
  15.   void dispose() {
  16.     _isDisposed = true;
  17.     super.dispose();
  18.   }
  19.  
  20.   /// Fetches the next page of data
  21.   Future<void> fetchNextPage() async {
  22.     final paging = state.pagingState;
  23.     if (paging.isLoading) return;
  24.  
  25.     final newPaging = paging.copyWith(isLoading: true, error: null);
  26.     state = state.copyWith(pagingState: newPaging);
  27.  
  28.     try {
  29.       final newKey = paging.keys?.last == null ? 0 : paging.keys!.last + 1;
  30.       final doctorResponse = await DoctorRepository.instance.getDoctors(
  31.         employeeId: _param.employeeId,
  32.         year: _param.year,
  33.         month: _param.month,
  34.         levelCode: _param.levelCode,
  35.         page: newKey,
  36.         term: _searchTerm,
  37.         selectedOnly: _param.selectedOnly,
  38.       );
  39.  
  40.       final doctorData = doctorResponse.data;
  41.  
  42.       final updatedPaging = paging.copyWith(
  43.         pages: [...?paging.pages, doctorData.doctors?.content ?? []],
  44.         keys: [...?paging.keys, newKey],
  45.         hasNextPage: doctorData.doctors?.hasNext,
  46.         isLoading: false,
  47.       );
  48.  
  49.       state = state.copyWith(
  50.         pagingState: updatedPaging,
  51.         totalDoctors: doctorData.doctors?.totalElements ?? 0,
  52.         selectedDoctors: doctorData.selectedDoctor ?? 0,
  53.         approved: doctorData.approved ?? true,
  54.         editable: doctorData.editable ?? false,
  55.       );
  56.  
  57.       // trigger the status message listener
  58.       doctorPlanApprovedNotifier.value = state.approved;
  59.     } catch (error) {
  60.       if (_isDisposed) return;
  61.       final failedPaging = paging.copyWith(
  62.         error: error,
  63.         isLoading: false,
  64.       );
  65.       state = state.copyWith(pagingState: failedPaging);
  66.     }
  67.   }
  68.  
  69.   /// Updates search term and refreshes the list
  70.   void updateSearchTerm(String searchTerm) {
  71.     _searchTerm = searchTerm;
  72.     refreshList();
  73.   }
  74.  
  75.   /// Refreshes the list and fetches the first page
  76.   void refreshList() {
  77.     state = state.copyWith(
  78.       pagingState: PagingState(),
  79.       totalDoctors: 0,
  80.       selectedDoctors: 0,
  81.       approved: false,
  82.     );
  83.     fetchNextPage();
  84.   }
  85.  
  86.   /// Method to toggle the selection of a Doctor
  87.   void toggleSelection(DoctorData content) {
  88.     final oldPaging = state.pagingState;
  89.     int updatedSelectedCount = state.selectedDoctors;
  90.  
  91.     final updatedPages = oldPaging.pages?.map((page) {
  92.       return page.map((c) {
  93.         if (c.doctor?.id == content.doctor?.id) {
  94.           final wasSelected = c.selected;
  95.           final nowSelected = !wasSelected;
  96.  
  97.           if (nowSelected) {
  98.             updatedSelectedCount++;
  99.           } else {
  100.             updatedSelectedCount--;
  101.           }
  102.  
  103.           return c.copyWith(selected: nowSelected);
  104.         }
  105.         return c;
  106.       }).toList();
  107.     }).toList();
  108.  
  109.     state = state.copyWith(
  110.       pagingState: oldPaging.copyWith(pages: updatedPages),
  111.       selectedDoctors: updatedSelectedCount,
  112.     );
  113.   }
  114. }
  115.  
  116. /// **Provider for ViewModel**
  117. final doctorListViewModelProvider =
  118.     StateNotifierProvider.family.autoDispose<DoctorListViewModel, DoctorPagingState, DefaultQueryParams>((ref, param) {
  119.   return DoctorListViewModel(param);
  120. });
  121.  
  122.  
  123. // --------------------------------------------------
  124.  
  125.  
  126. final doctorListState = ref.watch(doctorListViewModelProvider(_params));
  127. final doctorListViewModel = ref.read(doctorListViewModelProvider(_params).notifier);
  128.  
  129. PagedListView<int, DoctorData>.separated(
  130.   state: doctorListState.pagingState,
  131.   fetchNextPage: doctorListViewModel.fetchNextPage,
  132.   builderDelegate: PagedChildBuilderDelegate(
  133.     itemBuilder: (context, item, index) {
  134.       return DoctorListItem(
  135.         doctorData: item,
  136.         clickable: doctorListState.editable,
  137.         onClick: () => _toggleSelection(item, doctorListViewModel),
  138.       );
  139.     },
  140.   ),
  141.   separatorBuilder: (BuildContext context, int index) {
  142.     return const Divider(color: AppColors.dividerColor, height: 1);
  143.   },
  144. ),
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement