Proyek Kedua: Membangun Aplikasi Pencatat Catatan (Note App) Sederhana

📅 12 Agustus 2026 ☕ 2 min read
Proyek Kedua: Membangun Aplikasi Pencatat Catatan (Note App) Sederhana

Proyek Kedua: Membangun Aplikasi Pencatat Catatan (Note App) Sederhana

Setelah berhasil membangun tampilan UI statis pada proyek kartu nama, langkah logis berikutnya adalah membuat aplikasi yang lebih fungsional.

Artikel ini membahas cara membangun Aplikasi Pencatat Catatan, mengolah masukan pengguna (user input) dengan TextEditingController, serta menampilkan sekumpulan data secara dinamis menggunakan ListView.builder.

Komponen Utama yang Digunakan

  • TextEditingController: Objek yang bertugas membaca, mengontrol, dan membersihkan teks yang diketikkan pengguna ke dalam TextField.

  • ListView.builder: Widget efisien untuk merender daftar item secara dinamis. Widget ini hanya merekayasa visual item yang sedang tampil di layar, sehingga sangat hemat memori.

  • List<String>: Struktur data bawaan Dart untuk menyimpan daftar catatan secara sementara di dalam memori aplikasi.

Kode Lengkap Proyek

Dart
 
import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    debugShowCheckedModeBanner: false,
    home: AplikasiCatatan(),
  ));
}

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

  @override
  State<AplikasiCatatan> createState() => _AplikasiCatatanState();
}

class _AplikasiCatatanState extends State<AplikasiCatatan> {
  // 1. List penampung data catatan
  final List<String> _daftarCatatan = [];

  // 2. Controller untuk mengontrol TextField
  final TextEditingController _catatanController = TextEditingController();

  // 3. Fungsi untuk menambah catatan baru
  void _tambahCatatan() {
    final teks = _catatanController.text.trim();
    if (teks.isNotEmpty) {
      setState(() {
        _daftarCatatan.add(teks);
        _catatanController.clear(); // Kosongkan kolom input setelah disimpan
      });
    }
  }

  @override
  void dispose() {
    _catatanController.dispose(); // Bersihkan controller dari memori
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Catatan Sederhana'),
        backgroundColor: Colors.amber.shade700,
        foregroundColor: Colors.white,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // Area Input Teks
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _catatanController,
                    decoration: const InputDecoration(
                      labelText: 'Tulis catatan...',
                      border: OutlineInputBorder(),
                    ),
                  ),
                ),
                const SizedBox(width: 8),
                IconButton.filled(
                  onPressed: _tambahCatatan,
                  icon: const Icon(Icons.send),
                  backgroundColor: Colors.amber.shade700,
                ),
              ],
            ),
            const SizedBox(height: 20),

            // Area Menampilkan Daftar Catatan
            Expanded(
              child: _daftarCatatan.isEmpty
                  ? const Center(
                      child: Text(
                        'Belum ada catatan.',
                        style: TextStyle(color: Colors.grey),
                      ),
                    )
                  : ListView.builder(
                      itemCount: _daftarCatatan.length,
                      itemBuilder: (context, index) {
                        return Card(
                          margin: const EdgeInsets.symmetric(vertical: 4),
                          child: ListTile(
                            leading: CircleAvatar(
                              backgroundColor: Colors.amber.shade100,
                              foregroundColor: Colors.amber.shade900,
                              child: Text('${index + 1}'),
                            ),
                            title: Text(_daftarCatatan[index]),
                          ),
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

Bedah Jalurnya Kode

  1. Pembersihan Teks (_catatanController.clear()): Setelah teks ditambahkan ke dalam _daftarCatatan melalui metode add(), clear() memastiakan kolom input kembali kosong secara otomatis.

  2. Manajemen Memori (dispose()): Menghentikan dan menghapus TextEditingController saat widget tidak lagi digunakan untuk mencegah kebocoran memori (memory leak).

  3. Tampilan Kondisional: Menggunakan operator ternary (_daftarCatatan.isEmpty ? ... : ...) untuk menampilkan pesan "Belum ada catatan" saat data kosong, atau merender daftar ListView.builder saat data terisi.


+