Skip to content

Instantly share code, notes, and snippets.

@eduardoflorence
Created April 1, 2021 00:10
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save eduardoflorence/766b74f9bf421592a6664d6b38a2bcfe to your computer and use it in GitHub Desktop.
Save eduardoflorence/766b74f9bf421592a6664d6b38a2bcfe to your computer and use it in GitHub Desktop.
GetX - Sample ScrollMixin and Pagination
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