Skip to content

Commit

Permalink
add hive demo
Browse files Browse the repository at this point in the history
  • Loading branch information
X-Wei committed Nov 2, 2019
1 parent 4906dd0 commit 083bb91
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/my_app_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ import './routes/lists_listview_builder_ex.dart';
import './routes/lists_reorderable_ex.dart';
import './routes/lists_swipe_to_dismiss_ex.dart';
import './routes/nav_bottom_navbar_ex.dart';
import './routes/nav_bottom_sheet_ex.dart';
import './routes/nav_bottom_tabbar_ex.dart';
import './routes/nav_dialogs_ex.dart';
import './routes/nav_nav_drawer_header_ex.dart';
import './routes/nav_pageselector_ex.dart';
import './routes/nav_routes_ex.dart';
import './routes/nav_tabs_ex.dart';
import './routes/persistence_file_rw_ex.dart';
import './routes/persistence_hive_ex.dart';
import './routes/persistence_preference_ex.dart';
import './routes/persistence_sembast_ex.dart';
import './routes/persistence_sqlite_ex.dart';
Expand All @@ -65,7 +67,6 @@ import './routes/widgets_stateful_widgets_ex.dart';
import './routes/widgets_text_ex.dart';
import './routes/widgets_textfield_ex.dart';
import './routes/widgets_textformfield_ex.dart';
import 'routes/nav_bottom_sheet_ex.dart';

const kHomeRoute = MyRoute(
child: MyHomePage(),
Expand Down Expand Up @@ -411,7 +412,8 @@ const kMyAppRoutesStructure = <MyRouteGroup>[
sourceFilePath: 'lib/routes/nav_nav_bottom_sheet_ex.dart',
title: 'Bottom sheet',
links: {
'Medium article': 'https://medium.com/flutter-community/flutter-beginners-guide-to-using-the-bottom-sheet-b8025573c433',
'Medium article':
'https://medium.com/flutter-community/flutter-beginners-guide-to-using-the-bottom-sheet-b8025573c433',
},
),
MyRoute(
Expand Down Expand Up @@ -557,6 +559,18 @@ const kMyAppRoutesStructure = <MyRouteGroup>[
'https://resocoder.com/2019/04/06/flutter-nosql-database-sembast-tutorial-w-bloc/'
},
),
MyRoute(
child: HiveExample(),
sourceFilePath: 'lib/routes/persistence_sembast_ex.dart',
title: 'Hive',
description:
'Easier NoSQL db with less bolierplate code. Mini todo CRUD app.',
links: {
'Documentation': 'https://docs.hivedb.dev',
'ResoCoder blog':
'https://resocoder.com/2019/09/30/hive-flutter-tutorial-lightweight-fast-database'
},
),
],
),
MyRouteGroup(
Expand Down
24 changes: 24 additions & 0 deletions lib/routes/data/todo_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:hive/hive.dart';

// Generated by `flutter packages pub run build_runner build`.
part 'todo_item.g.dart';

@HiveType()
class TodoItem extends HiveObject {
@HiveField(0)
int id;
@HiveField(1)
String content;
@HiveField(2)
bool isDone;
@HiveField(3)
final DateTime createdAt;

TodoItem({this.id, this.content, this.isDone = false, createdAt})
: this.createdAt = createdAt ?? DateTime.now();

@override
String toString() {
return 'TodoItem(id=$id, content=$content, idDone=$isDone, createdAt=$createdAt)';
}
}
37 changes: 37 additions & 0 deletions lib/routes/data/todo_item.g.dart

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

169 changes: 169 additions & 0 deletions lib/routes/persistence_hive_ex.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import 'package:english_words/english_words.dart' as english_words;
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart' as path_provider;

import './data/todo_item.dart' show TodoItem, TodoItemAdapter;

// We use built_value and hive_generator to make serializable data class.
/* Content of the "./data/todo_item.dart" file:
import 'package:hive/hive.dart';
// Generated by `flutter packages pub run build_runner build`.
part 'todo_item.g.dart';
@HiveType()
class TodoItem extends HiveObject {
@HiveField(0)
int id;
@HiveField(1)
String content;
@HiveField(2)
bool isDone;
@HiveField(3)
final DateTime createdAt;
TodoItem({this.id, this.content, this.isDone = false, createdAt})
: this.createdAt = createdAt ?? DateTime.now();
@override
String toString() {
return 'TodoItem(id=$id, content=$content, idDone=$isDone, createdAt=$createdAt)';
}
} */

class HiveExample extends StatefulWidget {
const HiveExample({Key key}) : super(key: key);

@override
_HiveExampleState createState() => _HiveExampleState();
}

class _HiveExampleState extends State<HiveExample> {
static const kHiveFolder = 'hive';
static const kHiveBoxName = 'todosBox';

Future<bool> _initDbFuture;

@override
void initState() {
super.initState();
this._initDbFuture = this._initDb();
}

// Initializes the hive DB, once done the hive operations are *synchronous*.
Future<bool> _initDb() async {
// Initialize hive.
final hiveFolder = join(
(await path_provider.getApplicationDocumentsDirectory()).path,
kHiveFolder);
Hive.init(hiveFolder);
Hive.registerAdapter(TodoItemAdapter(), 0);
// Open the hive box so that we can later call Hive.box(<name>) to use it.
await Hive.openBox<TodoItem>(kHiveBoxName);
final List<TodoItem> todos = _getTodoItems();
print('Hive initialization done, todo items in the db are:');
for (final todo in todos) {
print(todo);
}
return true;
}

// Retrieves records from the hive box.
List<TodoItem> _getTodoItems() {
final box = Hive.box<TodoItem>(kHiveBoxName);
return box.values.toList();
}

// Inserts records to hive.
// Note we don't need to explicitly set the primary key (id), it'll auto
// increment.
Future<void> _addTodoItem(TodoItem todo) async {
final box = Hive.box<TodoItem>(kHiveBoxName);
int key = await box.add(todo);
// Set the id field to the auto-incremented key.
todo.id = key;
await todo.save();
print('Inserted: key=$key, value=$todo');
}

// Updates records in the db table.
Future<void> _toggleTodoItem(TodoItem todo) async {
// Since class TodoItem extends HiveObject, update the record is very easy.
// Note the `todo` must already been added to the hive box.
todo.isDone = !todo.isDone;
await todo.save();
print('Updated: key=${todo.id}, value=$todo');
}

// Deletes records in the db table.
Future<void> _deleteTodoItem(TodoItem todo) async {
// Since class TodoItem extends HiveObject, delete the object is very easy.
// Note the `todo` must already been added to the hive box.
await todo.delete();
print('Delted: key=${todo.id}, value=$todo');
}

@override
Widget build(BuildContext context) {
return FutureBuilder<bool>(
future: this._initDbFuture,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(),
);
return Scaffold(
// WatchBoxBuilder by hive_flutter can save us from writing a
// StreamBuilder ourselves.
body: WatchBoxBuilder(
box: Hive.box<TodoItem>(kHiveBoxName),
builder: (BuildContext context, Box box) => ListView(
children: <Widget>[
for (int i = 0; i < box.length; ++i)
_itemToListTile(box.getAt(i))
],
),
),
floatingActionButton: _buildFloatingActionButton(),
);
},
);
}

ListTile _itemToListTile(TodoItem todo) => ListTile(
title: Text(
todo.content,
style: TextStyle(
fontStyle: todo.isDone ? FontStyle.italic : null,
color: todo.isDone ? Colors.grey : null,
decoration: todo.isDone ? TextDecoration.lineThrough : null),
),
subtitle: Text('id=${todo.id}\ncreated at ${todo.createdAt}'),
isThreeLine: true,
leading: IconButton(
icon: Icon(
todo.isDone ? Icons.check_box : Icons.check_box_outline_blank),
onPressed: () => _toggleTodoItem(todo),
),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _deleteTodoItem(todo),
),
);

FloatingActionButton _buildFloatingActionButton() {
return FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
await _addTodoItem(
TodoItem(
content: english_words.generateWordPairs().first.asPascalCase,
),
);
},
);
}
}
4 changes: 4 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ dependencies:
flutter_webview_plugin: '0.3.5'
fluttertoast: '3.1.0'
google_sign_in: '4.0.2'
hive: '1.1.1'
hive_flutter: '0.2.1'
image_picker: '0.6.0+11'
local_auth: '0.5.2+4'
package_info: '0.4.0+4'
Expand All @@ -53,6 +55,8 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
hive_generator: '0.5.2'
build_runner: '1.7.1'

# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
Expand Down

0 comments on commit 083bb91

Please sign in to comment.