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

السحب للتحديث

جزء من قسم البيانات والشبكة في رحلة Flutter على Coddy. الدرس 9 من 27.

على الهاتف، يسحب الأشخاص القائمة إلى الأسفل لإعادة تحميلها. يظهر مؤشر التحميل من الأعلى، ثم تُحدَّث البيانات. الأداة المصغّرة في Flutter لهذه الوظيفة هي RefreshIndicator:

RefreshIndicator(
  onRefresh: refresh,
  child: ListView(
    children: [ ... ],
  ),
)

onRefresh هي دالة تُرجع Future. يظل مؤشر السحب ظاهرًا إلى أن تنتهي تلك المهمة المستقبلية، لذا استخدم await لانتظار البيانات الجديدة بداخلها:

Future<void> refresh() async {
  setState(() {
    _tip = fetch('/tip');
  });
  await _tip;
}

لا يعمل السحب إلا على محتوى قابل للتمرير. ضع المحتوى في ListView، حتى عندما يكون عنصرًا واحدًا: يمكن دائمًا السحب في ListView. يشير مؤشر السحب بالفعل إلى أن التطبيق يعمل، لذا يمكن للباني الإبقاء على النصيحة القديمة باستخدام التحقق من hasData.

challenge icon

التحدي

متوسط

اجعل النصيحة تُحمَّل من جديد عند سحب الشاشة إلى الأسفل:

  • أضف طريقة refresh تعيّن _tip جديدًا داخل setState وتنتظره
  • أحط محتوى الجسم بـ RefreshIndicator مع onRefresh: refresh
  • ضع FutureBuilder داخل ListView ضمنه

في المعاينة، اسحب الشاشة إلى الأسفل باستخدام الفأرة.

جرّب بنفسك

import 'package:flutter/material.dart';

import 'api.dart';

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

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

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

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

  @override
  State<TipScreen> createState() => _TipScreenState();
}

class _TipScreenState extends State<TipScreen> {
  late Future<String> _tip;

  @override
  void initState() {
    super.initState();
    _tip = fetch('/tip');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Tip of the Day'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: FutureBuilder<String>(
              future: _tip,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Text(
                    snapshot.data!,
                    textAlign: TextAlign.center,
                    style: const TextStyle(fontSize: 24),
                  );
                }
                return const CircularProgressIndicator();
              },
            ),
        ),
      ),
    );
  }
}
quiz iconاختبر نفسك

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

جميع دروس البيانات والشبكة

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