Menu
CoddyTech

İki Ekran, Tek Model

Coddy'nin Flutter Journey'sinin Durum Yönetimi bölümünün bir parçası. Ders 13 / 27.

İki ekran arasında paylaşılan veriler, Provider'ın işe yaradığı yerdir. Ayarlar ekranı adı değiştirir, ana ekran da bunu gösterir; iki ekranın birbirine herhangi bir şey aktarmasına gerek kalmaz.

Sağlayıcının nerede bulunduğu önemlidir. MaterialApp bir Navigator içerir ve açtığınız her ekran, home'un içine değil, onun yanına eklenir:

ChangeNotifierProvider        <- above MaterialApp: every screen finds it
  MaterialApp
    Navigator
      HomePage
      SettingsScreen          <- pushed next to HomePage

HomePage'in etrafına sarılmış bir sağlayıcı yalnızca HomePage'e ulaşır. Açılan ekran onun altında değildir, bu yüzden modeli bulamaz. Sağlayıcıyı main içinde MaterialApp'in üstüne koyun; böylece tüm ekranlar onu paylaşır.

Diğer ekrana ikinci bir ChangeNotifierProvider ekleyerek hatayı düzeltmeye çalışmayın. Bu, ikinci bir model oluşturur: hata ortadan kalkar, ancak ekranlar artık hiçbir şeyi paylaşmaz.

challenge icon

Görev

Orta

Dișli simgesine dokun, bir ad yaz ve Save düğmesine bas: uygulama hata gösteriyor, çünkü sağlayıcı yalnızca HomePage öğesini sarıyor.

  • ChangeNotifierProvider öğesini MyApp dışına taşı ve main içinde, MyApp öğesinin etrafına yerleştir.

Ardından Ada adını kaydettiğinde ana ekranda Hello, Ada! görünür.

Kendin dene

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

class Profile extends ChangeNotifier {
  String _name = 'Guest';

  String get name => _name;

  void rename(String newName) {
    _name = newName;
    notifyListeners();
  }
}

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ChangeNotifierProvider(
        create: (context) => Profile(),
        child: const HomePage(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final profile = context.watch<Profile>();
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
        actions: [
          IconButton(
            icon: const Icon(Icons.settings),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const SettingsScreen()),
              );
            },
          ),
        ],
      ),
      body: Center(
        child: Text('Hello, ${profile.name}!', style: const TextStyle(fontSize: 32)),
      ),
    );
  }
}

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

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

class _SettingsScreenState extends State<SettingsScreen> {
  final controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final profile = context.watch<Profile>();
    return Scaffold(
      appBar: AppBar(title: const Text('Settings')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Text('Signed in as ${profile.name}'),
            const SizedBox(height: 16),
            TextField(
              controller: controller,
              decoration: const InputDecoration(labelText: 'Your name'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                context.read<Profile>().rename(controller.text);
                Navigator.pop(context);
              },
              child: const Text('Save'),
            ),
          ],
        ),
      ),
    );
  }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Durum Yönetimi bölümündeki tüm dersler

Kendi başına pratik yap: Online Flutter derleyicisi