Menu
CoddyTech

Memilih Tempat State Disimpan

Termasuk bagian Pengelolaan State dalam perjalanan Flutter di Coddy. Pelajaran 21 dari 27.

Sakelar mode gelap di layar Settings bergerak, tetapi tidak ada yang menjadi gelap. Nilainya tetap tersimpan dengan setState, dan hanya sakelar itu yang dapat melihatnya. Tema diatur jauh dari sana, di MyApp. Nilai ini milik seluruh aplikasi.

Setiap nilai dalam aplikasi membutuhkan tempat. Tanyakan siapa yang menggunakannya:

  • Satu widget (teks sebuah field, panel yang terbuka, indeks tab): setState di widget itu.
  • Beberapa widget yang berdekatan (tombol dan label di sebelahnya): pindahkan ke parent-nya, lalu teruskan ke bawah.
  • Banyak widget atau beberapa layar (pengguna, cart, pengaturan): model bersama dengan Provider atau Riverpod.

Provider atau Riverpod? Keduanya bisa digunakan. Provider sedikit lebih sederhana dan menempatkan model di widget tree, yang ditemukan melalui context. Riverpod menyimpan provider di luar tree, sehingga nilai tidak membutuhkan context, dan provider dapat mengawasi satu sama lain. Pilih salah satu untuk sebuah aplikasi dan gunakan di seluruh aplikasi.

Di sini, StateProvider cocok: satu bool, dibaca oleh MyApp untuk memilih tema, dan diubah oleh sakelar:

final darkModeProvider = StateProvider((ref) => false);

// di MyApp, sekarang menjadi ConsumerWidget:
themeMode: ref.watch(darkModeProvider) ? ThemeMode.dark : ThemeMode.light,
challenge icon

Tantangan

Sulit

Buat sakelar mode gelap mengubah seluruh aplikasi:

  • Tambahkan final darkModeProvider = StateProvider((ref) => false); di bagian atas.
  • Ubah MyApp menjadi ConsumerWidget yang themeMode-nya mengikuti provider.
  • Ubah SettingsScreen menjadi ConsumerWidget: sakelar menampilkan nilai provider dan mengaturnya saat berubah.

Coba sendiri

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

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.light,
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Notes'),
        actions: [
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const SettingsScreen()),
              );
            },
          ),
        ],
      ),
      body: const Center(child: Text('No notes yet')),
    );
  }
}

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

  @override
  State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  bool dark = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Settings')),
      body: ListView(
        children: [
          SwitchListTile(
            title: const Text('Dark mode'),
            value: dark,
            onChanged: (value) {
              setState(() {
                dark = value;
              });
            },
          ),
        ],
      ),
    );
  }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pengelolaan State

Latihan sendiri: Compiler Flutter online