Menu
CoddyTech
flag Ar iconالعربيةdown icon

Provider: المستهلك

جزء من قسم إدارة الحالة في رحلة Flutter على Coddy. الدرس 12 من 27.

هنا يُنشأ المزوّد داخل build الخاص بـ MyApp، ويطلب build نفسه المصباح أسفله مباشرةً. يعرض التطبيق خطأً: ينتمي context إلى MyApp، الذي يقع فوق المزوّد، ولا يمكن للأداة العثور إلا على المزوّدات التي تقع فوقها.

يحلّ Consumer هذه المشكلة. فهو أداة، لذا يقع أسفل المزوّد، ويحصل builder الخاص به على context جديد وعلى النموذج نفسه:

Consumer<Lamp>(
  builder: (context, lamp, child) {
    return Text(lamp.isOn ? 'On' : 'Off');
  },
)

يُنفَّذ builder مجددًا كلما استدعى المصباح notifyListeners()، مثل أداة تراقبه. وداخله، يمكنك استدعاء أساليب النموذج مباشرةً على lamp: onPressed: () => lamp.toggle().

كما أن Consumer يعيد بناء الجزء الذي يغلّفه فقط، لذا فإن تغليف الجزء الذي يتغير يُبقي بقية الشاشة كما هي. في معظم التطبيقات، ستستخدم context.watch داخل أداة مستقلة، وستلجأ إلى Consumer عندما تكون في build نفسه الذي يحتوي على المزوّد.

challenge icon

التحدي

متوسط

يبدأ التطبيق بعرض خطأ. ضع أجزاء المصباح داخل Consumer:

  • غلّف Column بـ Consumer<Lamp> وأعِد Column من الدالة البانية الخاصة به.
  • استخدم داخلها lamp التابعة للدالة البانية للأيقونة والنص والزر.

جرّب بنفسك

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

class Lamp extends ChangeNotifier {
  bool _isOn = false;

  bool get isOn => _isOn;

  void toggle() {
    _isOn = !_isOn;
    notifyListeners();
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Lamp(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(title: const Text('Lamp')),
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
                  size: 96,
                  color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
                ),
                Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => context.read<Lamp>().toggle(),
                  child: const Text('Switch'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس إدارة الحالة

تدرّب بنفسك: مترجم Flutter عبر الإنترنت