Menu
CoddyTech

Diğer Provider'ları İzleyen Provider'lar

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

Bazı durumlar diğer durumlardan türetilir: toplam dakika, antrenmanların toplamıdır. Toplamı gösteren her widget'ta bunları toplayabilir ya da başka bir sağlayıcıyı izleyen bir sağlayıcı olarak bunu bir kez yazabilirsin:

final totalMinutesProvider = Provider((ref) {
  final workouts = ref.watch(workoutsProvider);
  return workouts.fold(0, (sum, w) => sum + w.minutes);
});

Bir sağlayıcının işlevi de ref alır. İçinde ref.watch kullandığında Riverpod, toplamın antrenmanlara bağlı olduğunu hatırlar. Bir antrenman ekle; toplam yeniden hesaplanır ve toplamı izleyen her widget yeniden oluşturulur.

Burada ref.read yerine ref.watch kullan. read, listeyi yalnızca toplam ilk kez hesaplandığında alır ve sonrasında toplam hiç değişmez.

Bu, daha önceki getter fikrinin tüm uygulamaya uygulanmış hâlidir: olabildiğince az şeyi sakla ve geri kalanını bunlardan hesapla.

challenge icon

Görev

Orta

Üst çubuk totalMinutesProvider'ı izliyor, ancak bu sağlayıcı her zaman 0 döndürüyor.

  • workoutsProvider'ı izlemesini ve her antrenmanın minutes değerlerinin toplamını döndürmesini sağlayın.

Kendin dene

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

class Workout {
  Workout(this.name, this.minutes);

  final String name;
  final int minutes;
}

class WorkoutLog extends Notifier<List<Workout>> {
  @override
  List<Workout> build() => [];

  void add(Workout workout) {
    state = [...state, workout];
  }
}

final workoutsProvider = NotifierProvider<WorkoutLog, List<Workout>>(WorkoutLog.new);

final totalMinutesProvider = Provider((ref) {
  return 0;
});

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

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

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

class LogPage extends ConsumerWidget {
  const LogPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final workouts = ref.watch(workoutsProvider);
    final total = ref.watch(totalMinutesProvider);
    return Scaffold(
      appBar: AppBar(title: Text('Total: $total min')),
      body: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () => ref.read(workoutsProvider.notifier).add(Workout('Run', 30)),
                child: const Text('Run'),
              ),
              const SizedBox(width: 16),
              ElevatedButton(
                onPressed: () => ref.read(workoutsProvider.notifier).add(Workout('Yoga', 20)),
                child: const Text('Yoga'),
              ),
            ],
          ),
          Expanded(
            child: ListView(
              children: [
                for (final w in workouts) ListTile(title: Text(w.name), trailing: Text('${w.minutes} min')),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
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