Skip to content
Open

Nnbd #19

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# load_more_flutter_BLoC_pattern_RxDart_and_RxRedux 📱
- Load more Flutter BLoC pattern RxDart and RxRedux.
- Load more data when scrolling to end of list view.
- Paging `ListView Flutter`.
- Infinite scroll `ListView Flutter`.
- Load more data when scrolling to end of ListView, GridView, CustomScrollView.
- Paging `ListView, GridView, CustomScrollView Flutter`.
- Infinite scroll `ListView, GridView, CustomScrollView Flutter`.

## Find this repository useful? ❤️

Expand Down
4 changes: 2 additions & 2 deletions lib/generated/intl/messages_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Map<String, LibraryLoader> _deferredLibraries = {
'vi': () => new Future.value(null),
};

MessageLookupByLibrary _findExact(String localeName) {
MessageLookupByLibrary? _findExact(String localeName) {
switch (localeName) {
case 'en':
return messages_en.messages;
Expand Down Expand Up @@ -59,7 +59,7 @@ bool _messagesExistFor(String locale) {
}
}

MessageLookupByLibrary _findGeneratedMessagesFor(String locale) {
MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
onFailure: (_) => null);
if (actualLocale == null) return null;
Expand Down
45 changes: 27 additions & 18 deletions lib/generated/l10n.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 20 additions & 19 deletions lib/pages/comics/comics_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_disposebag/flutter_disposebag.dart';
import 'package:load_more_flutter/data/comics/comic_repository_impl.dart';
import 'package:load_more_flutter/generated/l10n.dart';
import 'package:load_more_flutter/pages/comics/bloc/comic.dart';
Expand All @@ -12,14 +13,12 @@ class ComicsPage extends StatefulWidget {
_ComicsPageState createState() => _ComicsPageState();
}

class _ComicsPageState extends State<ComicsPage> {
class _ComicsPageState extends State<ComicsPage> with DisposeBagMixin {
static const offsetVisibleThreshold = 200;

ComicsBloc _comicsBloc;
StreamSubscription<Message> _subscription;

Object token;
ScrollController _scrollController;
final _scaffoldKey = GlobalKey<ScaffoldState>();

@override
void initState() {
Expand All @@ -39,17 +38,6 @@ class _ComicsPageState extends State<ComicsPage> {
ComicsListType.updated.toString(),
);

_subscription = _comicsBloc.message$.listen((message) {
if (message is LoadAllComicsMessage) {
_scaffoldKey.showSnackBar(S.of(context).loaded_all_people);
makeAnimation();
}
if (message is ErrorMessage) {
final error = message.error;
_scaffoldKey
.showSnackBar(S.of(context).error_occurred(error.toString()));
}
});
_comicsBloc.loadFirstPage();
}

Expand All @@ -72,19 +60,32 @@ class _ComicsPageState extends State<ComicsPage> {
);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();

token ??= _comicsBloc.message$.listen((message) {
if (message is LoadAllComicsMessage) {
context.showSnackBar(S.of(context).loaded_all_people);
makeAnimation();
}
if (message is ErrorMessage) {
final error = message.error;
context.showSnackBar(S.of(context).error_occurred(error.toString()));
}
}).disposedBy(bag);
}

@override
void dispose() {
super.dispose();
_scrollController.dispose();
_subscription.cancel();
_comicsBloc.dispose();

super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Comics page'),
),
Expand Down
37 changes: 21 additions & 16 deletions lib/pages/comics/widgets/comic_horizontal_list.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_disposebag/flutter_disposebag.dart';
import 'package:load_more_flutter/data/comics/comic_repository_impl.dart';
import 'package:load_more_flutter/generated/l10n.dart';
import 'package:load_more_flutter/pages/comics/bloc/comics_bloc.dart';
Expand All @@ -20,12 +21,12 @@ class ComicsHorizontalListView extends StatefulWidget {
_ComicsHorizontalListViewState();
}

class _ComicsHorizontalListViewState extends State<ComicsHorizontalListView> {
class _ComicsHorizontalListViewState extends State<ComicsHorizontalListView>
with DisposeBagMixin {
static const offsetVisibleThreshold = 50.0;

ComicsBloc _comicsBloc;
StreamSubscription<Message> _subscription;

Object token;
ScrollController _scrollController;

@override
Expand Down Expand Up @@ -55,16 +56,6 @@ class _ComicsHorizontalListViewState extends State<ComicsHorizontalListView> {
widget.listType.toString(),
);

_subscription = _comicsBloc.message$.listen((message) {
if (message is LoadAllComicsMessage) {
context.showSnackBar(S.of(context).loaded_all_people);
makeAnimation();
}
if (message is ErrorMessage) {
final error = message.error;
context.showSnackBar(S.of(context).error_occurred(error.toString()));
}
});
_comicsBloc.loadFirstPage();
}

Expand All @@ -87,13 +78,27 @@ class _ComicsHorizontalListViewState extends State<ComicsHorizontalListView> {
);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();

token ??= _comicsBloc.message$.listen((message) {
if (message is LoadAllComicsMessage) {
context.showSnackBar(S.of(context).loaded_all_people);
makeAnimation();
}
if (message is ErrorMessage) {
final error = message.error;
context.showSnackBar(S.of(context).error_occurred(error.toString()));
}
}).disposedBy(bag);
}

@override
void dispose() {
super.dispose();
_scrollController.dispose();
_subscription.cancel();
_comicsBloc.dispose();

super.dispose();
}

@override
Expand Down
38 changes: 20 additions & 18 deletions lib/pages/home_page/home_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_disposebag/flutter_disposebag.dart';
import 'package:load_more_flutter/data/people/memory_person_data_source.dart';
import 'package:load_more_flutter/data/people/people_api.dart';
import 'package:load_more_flutter/generated/l10n.dart';
Expand All @@ -13,26 +14,19 @@ class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
class _MyHomePageState extends State<MyHomePage> with DisposeBagMixin {
final _scrollController = ScrollController();
final _scaffoldKey = GlobalKey<ScaffoldState>();
static const offsetVisibleThreshold = 50;

///
/// pass [PeopleApi] or [MemoryPersonDataSource] to [PeopleBloc]'s constructor
///
PeopleBloc _bloc;
StreamSubscription<void> _subscriptionReachMaxItems;
StreamSubscription<Object> _subscriptionError;
Object token;

@override
void initState() {
super.initState();

_bloc = PeopleBloc(PeopleApi());
// listen error, reach max items
_subscriptionReachMaxItems = _bloc.loadedAllPeople.listen(_onReachMaxItem);
_subscriptionError = _bloc.error.listen(_onError);

// add listener to scroll controller
_scrollController.addListener(_onScroll);
Expand All @@ -41,21 +35,26 @@ class _MyHomePageState extends State<MyHomePage> {
_bloc.loadFirstPage.add(null);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
// listen error, reach max items
token ??= [
_bloc.loadedAllPeople.listen(_onReachMaxItem),
_bloc.error.listen(_onError),
].disposedBy(bag);
}

@override
void dispose() {
super.dispose();
_scrollController.dispose();

_subscriptionError.cancel();
_subscriptionReachMaxItems.cancel();
_bloc.dispose();

super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Load more flutter'),
),
Expand Down Expand Up @@ -121,7 +120,10 @@ class _MyHomePageState extends State<MyHomePage> {
return ListTile(
title: Text(
S.of(context).error_occurred_loading_next_page(error.toString()),
style: Theme.of(context).textTheme.bodyText2.copyWith(fontSize: 16.0),
style: Theme.of(context)
.textTheme
.bodyText2
.copyWith(fontSize: 16.0),
),
isThreeLine: false,
leading: CircleAvatar(
Expand Down Expand Up @@ -173,10 +175,10 @@ class _MyHomePageState extends State<MyHomePage> {
void _onReachMaxItem(void _) async {
// show animation when loaded all data
await makeAnimation();
_scaffoldKey.showSnackBar(S.of(context).loaded_all_people);
context.showSnackBar(S.of(context).loaded_all_people);
}

void _onError(Object error) {
_scaffoldKey.showSnackBar(S.of(context).error_occurred(error.toString()));
context.showSnackBar(S.of(context).error_occurred(error.toString()));
}
}
Loading