Created
April 1, 2021 00:10
-
-
Save eduardoflorence/766b74f9bf421592a6664d6b38a2bcfe to your computer and use it in GitHub Desktop.
GetX - Sample ScrollMixin and Pagination
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:get/get.dart'; | |
void main() { | |
runApp(GetMaterialApp( | |
initialRoute: '/home', | |
getPages: [ | |
GetPage( | |
name: '/home', | |
page: () => HomePage(), | |
), | |
GetPage( | |
name: '/git-repositories', | |
page: () => GitRepositoryPage(), | |
binding: GitRepositoryBinding(), | |
), | |
], | |
)); | |
} | |
class HomePage extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('HOME')), | |
body: Center( | |
child: ElevatedButton( | |
onPressed: () => Get.toNamed('/git-repositories'), | |
child: Text('View GitHub Repositories'), | |
), | |
), | |
); | |
} | |
} | |
class GitRepositoryBinding extends Bindings { | |
@override | |
void dependencies() { | |
Get.lazyPut(() => GitRepositoryProvider()); | |
Get.put(GitRepositoryController(provider: Get.find())); | |
} | |
} | |
class GitRepositoryModel { | |
GitRepositoryModel({ | |
required this.fullName, | |
required this.description, | |
required this.url, | |
}); | |
String fullName; | |
String description; | |
String url; | |
factory GitRepositoryModel.fromJson(Map<String, dynamic> json) => | |
GitRepositoryModel( | |
fullName: json['full_name'], | |
description: json['description'] ?? 'No description', | |
url: json['html_url'], | |
); | |
static List<GitRepositoryModel> listFromJson(list) => | |
List<GitRepositoryModel>.from( | |
list.map((x) => GitRepositoryModel.fromJson(x))); | |
} | |
class GitRepositoryController extends GetxController | |
with StateMixin<List<GitRepositoryModel>>, ScrollMixin { | |
final GitRepositoryProvider provider; | |
GitRepositoryController({required this.provider}); | |
List<GitRepositoryModel> repositories = []; | |
final int repositoriesPerPage = 10; | |
int page = 1; | |
bool getFirstData = false; | |
bool lastPage = false; | |
@override | |
void onInit() { | |
findAllGitRepositories(); | |
super.onInit(); | |
} | |
Future<void> findAllGitRepositories() async { | |
await provider.getGitRepositories(repositoriesPerPage, page).then((result) { | |
final bool emptyRepositories = result.body?.isEmpty ?? true; | |
if (!getFirstData && emptyRepositories) { | |
change(null, status: RxStatus.empty()); | |
} else if (getFirstData && emptyRepositories) { | |
lastPage = true; | |
} else { | |
getFirstData = true; | |
repositories.addAll(result.body!); | |
change(repositories, status: RxStatus.success()); | |
} | |
}, onError: (err) { | |
change(null, status: RxStatus.error(err.toString())); | |
}); | |
} | |
@override | |
Future<void> onEndScroll() async { | |
print('onEndScroll'); | |
if (!lastPage) { | |
page += 1; | |
Get.dialog(Center(child: LinearProgressIndicator())); | |
await findAllGitRepositories(); | |
Get.back(); | |
} else { | |
Get.snackbar('Alert', 'End of Repositories'); | |
} | |
} | |
@override | |
Future<void> onTopScroll() async { | |
print('onTopScroll'); | |
} | |
} | |
class GitRepositoryProvider extends GetConnect { | |
final String org = 'flutter'; | |
@override | |
void onInit() { | |
// All request will pass to jsonEncode so CasesModel.fromJson() | |
httpClient.defaultDecoder = GitRepositoryModel.listFromJson; | |
httpClient.baseUrl = 'https://api.github.com/orgs'; | |
} | |
Future<Response<List<GitRepositoryModel>>> getGitRepositories( | |
int itemsPerPage, int page) => | |
get<List<GitRepositoryModel>>( | |
'/$org/repos?per_page=$itemsPerPage&page=$page', | |
// query: {'orderBy': 'nome'}, | |
decoder: GitRepositoryModel.listFromJson, | |
); | |
} | |
class GitRepositoryPage extends GetView<GitRepositoryController> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Repositories')), | |
body: Container( | |
child: controller.obx( | |
(state) => ListView.builder( | |
controller: controller.scroll, | |
itemCount: state?.length, | |
itemBuilder: (context, index) { | |
final GitRepositoryModel repository = state![index]; | |
return ListTile( | |
isThreeLine: true, | |
leading: Text( | |
(++index).toString(), | |
style: TextStyle(fontSize: 20), | |
), | |
title: Text(repository.fullName), | |
subtitle: | |
Text('${repository.description}\n${repository.url}'), | |
); | |
}, | |
), | |
onLoading: Center(child: LinearProgressIndicator()), | |
onEmpty: Center( | |
child: Text( | |
'Repositories no found', | |
style: TextStyle(fontSize: 18), | |
textAlign: TextAlign.center, | |
), | |
), | |
onError: (error) => Center( | |
child: Text( | |
'Error: Cannot get repositories \n$error', | |
style: TextStyle(fontSize: 18), | |
textAlign: TextAlign.center, | |
), | |
), | |
), | |
)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment