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

تطبيق الطقس: الأيام الثلاثة القادمة

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

تحتوي الإجابة الخاصة بالمدينة أيضًا على توقعات الطقس: قائمة JSON داخل الكائن، وعنصر واحد لكل يوم.

"forecast": [
  {"date": "2026-10-20", "condition": "Cloudy", "high": 22, "low": 15},
  ...
]

تُقرأ القائمة داخل الكائن بالطريقة نفسها التي تُقرأ بها القائمة المستقلة: استخرجها باستخدام as List<dynamic>، ثم طبّق map على كل عنصر باستخدام fromJson الخاص به. ألقِ نظرة على Weather.fromJson في أسفل الملف: فهو يفعل ذلك بالفعل، لذا فإن weather.forecast هي List<DayForecast>.

final days = json['forecast'] as List<dynamic>;

forecast: days
    .map((day) => DayForecast.fromJson(day as Map<String, dynamic>))
    .toList(),

لكل يوم قيمة DateTime. تحوّل DateFormat('EEEE') هذه القيمة إلى الاسم الكامل ليوم الأسبوع، مثل الثلاثاء. وتُنشئ حلقة for داخل أبناء Column صفًا واحدًا لكل يوم.

challenge icon

التحدي

متوسط

اعرض الأيام الثلاثة التالية أسفل الطقس الحالي:

  • استورد package:intl/intl.dart
  • بعد SizedBox(height: 32)، أضف Row لكل يوم: اعرض اسم يوم الأسبوع باستخدام DateFormat('EEEE') داخل Expanded، ثم درجتي الحرارة العظمى والصغرى بهذا الشكل 22° / 15°
  • أضف لكل صف مساحة داخلية قدرها 32 بكسل على اليمين واليسار

جرّب بنفسك

import 'dart:convert';

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: WeatherScreen(),
    );
  }
}

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

  @override
  State<WeatherScreen> createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  late Future<Weather> _weather;

  @override
  void initState() {
    super.initState();
    _weather = loadWeather();
  }

  Future<Weather> loadWeather() async {
    final body = await fetch('/weather/lisbon');
    return Weather.fromJson(jsonDecode(body));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Weather')),
      body: Center(
        child: FutureBuilder<Weather>(
          future: _weather,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Could not load: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              return buildWeather(snapshot.data!);
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }

  Widget buildWeather(Weather weather) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(weather.city, style: const TextStyle(fontSize: 32)),
        Text(
          '${weather.temperature}°',
          style: const TextStyle(fontSize: 72, fontWeight: FontWeight.bold),
        ),
        Text(weather.condition, style: const TextStyle(fontSize: 24)),
      ],
    );
  }
}

class Weather {
  Weather({
    required this.city,
    required this.temperature,
    required this.condition,
    required this.forecast,
  });

  final String city;
  final int temperature;
  final String condition;
  final List<DayForecast> forecast;

  factory Weather.fromJson(Map<String, dynamic> json) {
    final days = json['forecast'] as List<dynamic>;
    return Weather(
      city: json['city'] as String,
      temperature: json['temperature'] as int,
      condition: json['condition'] as String,
      forecast: days
          .map((day) => DayForecast.fromJson(day as Map<String, dynamic>))
          .toList(),
    );
  }
}

class DayForecast {
  DayForecast({
    required this.date,
    required this.condition,
    required this.high,
    required this.low,
  });

  final DateTime date;
  final String condition;
  final int high;
  final int low;

  factory DayForecast.fromJson(Map<String, dynamic> json) {
    return DayForecast(
      date: DateTime.parse(json['date'] as String),
      condition: json['condition'] as String,
      high: json['high'] as int,
      low: json['low'] as int,
    );
  }
}
quiz iconاختبر نفسك

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

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

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