0
0
Fluttermobile~20 mins

Hive for NoSQL storage in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Simple Hive Storage
A screen to add, display, and delete simple text items stored locally using Hive NoSQL database.
Target UI
-------------------------
| Simple Hive Storage    |
-------------------------
| [TextField           ] |
| [Add Item Button     ] |
|-----------------------|
| Items:                |
| 1. Example item       |
| 2. Another item       |
|                       |
-------------------------
Use Hive to store a list of strings locally.
Display all stored items in a scrollable list.
Add a TextField to input new items.
Add a button to save the new item to Hive and update the list.
Allow deleting an item by tapping on it.
Initialize Hive properly and open a box named 'itemsBox'.
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocumentDir = await getApplicationDocumentsDirectory();
  Hive.init(appDocumentDir.path);
  await Hive.openBox<String>('itemsBox');
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: SimpleHiveStorageScreen(),
    );
  }
}

class SimpleHiveStorageScreen extends StatefulWidget {
  const SimpleHiveStorageScreen({super.key});

  @override
  State<SimpleHiveStorageScreen> createState() => _SimpleHiveStorageScreenState();
}

class _SimpleHiveStorageScreenState extends State<SimpleHiveStorageScreen> {
  final TextEditingController _controller = TextEditingController();
  late Box<String> itemsBox;

  @override
  void initState() {
    super.initState();
    itemsBox = Hive.box<String>('itemsBox');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Simple Hive Storage')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(labelText: 'Enter new item'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                // TODO: Add item to Hive and update UI
              },
              child: const Text('Add Item'),
            ),
            const SizedBox(height: 20),
            const Text('Items:'),
            Expanded(
              child: ValueListenableBuilder(
                valueListenable: Hive.box<String>('itemsBox').listenable(),
                builder: (context, Box<String> box, _) {
                  if (box.isEmpty) {
                    return const Center(child: Text('No items added yet'));
                  }
                  return ListView.builder(
                    itemCount: box.length,
                    itemBuilder: (context, index) {
                      final item = box.getAt(index);
                      return ListTile(
                        title: Text(item ?? ''),
                        onTap: () {
                          // TODO: Delete tapped item
                        },
                      );
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDocumentDir = await getApplicationDocumentsDirectory();
  Hive.init(appDocumentDir.path);
  await Hive.openBox<String>('itemsBox');
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: SimpleHiveStorageScreen(),
    );
  }
}

class SimpleHiveStorageScreen extends StatefulWidget {
  const SimpleHiveStorageScreen({super.key});

  @override
  State<SimpleHiveStorageScreen> createState() => _SimpleHiveStorageScreenState();
}

class _SimpleHiveStorageScreenState extends State<SimpleHiveStorageScreen> {
  final TextEditingController _controller = TextEditingController();
  late Box<String> itemsBox;

  @override
  void initState() {
    super.initState();
    itemsBox = Hive.box<String>('itemsBox');
  }

  void _addItem() {
    final text = _controller.text.trim();
    if (text.isNotEmpty) {
      itemsBox.add(text);
      _controller.clear();
    }
  }

  void _deleteItem(int index) {
    itemsBox.deleteAt(index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Simple Hive Storage')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(labelText: 'Enter new item'),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: _addItem,
              child: const Text('Add Item'),
            ),
            const SizedBox(height: 20),
            const Text('Items:'),
            Expanded(
              child: ValueListenableBuilder(
                valueListenable: itemsBox.listenable(),
                builder: (context, Box<String> box, _) {
                  if (box.isEmpty) {
                    return const Center(child: Text('No items added yet'));
                  }
                  return ListView.builder(
                    itemCount: box.length,
                    itemBuilder: (context, index) {
                      final item = box.getAt(index);
                      return ListTile(
                        title: Text(item ?? ''),
                        onTap: () => _deleteItem(index),
                      );
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

This app uses Hive to store a list of strings locally on the device. We initialize Hive with the app documents directory and open a box named 'itemsBox' to hold our strings.

The UI has a TextField to enter new items and a button to add them. When the button is pressed, the text is trimmed and added to the Hive box, then the TextField is cleared.

The list of stored items is shown below using a ValueListenableBuilder that listens to changes in the Hive box. This automatically updates the UI when items are added or deleted.

Tapping an item deletes it from the box, which also updates the list instantly.

This simple example shows how Hive can be used for local NoSQL storage with reactive UI updates in Flutter.

Final Result
Completed Screen
-------------------------
| Simple Hive Storage    |
-------------------------
| [TextField           ] |
| [Add Item Button     ] |
|-----------------------|
| Items:                |
| 1. Example item       |
| 2. Another item       |
|                       |
-------------------------
User types text in the TextField and taps 'Add Item' to save it locally.
The new item appears in the list below immediately.
User taps any item in the list to delete it from storage and remove it from the list.
Stretch Goal
Add a confirmation dialog before deleting an item.
💡 Hint
Use showDialog with AlertDialog to ask user to confirm deletion before calling deleteAt.