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

تطبيق الطقس: أيقونات الطقس

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

يقرأ الناس رمز الشمس أسرع من كلمة Sunny. حوّل كل حالة إلى رمز باستخدام دالة واحدة، واستخدمها أينما ظهرت حالة.

يختار تعبير switch قيمةً لكل حالة، ويستخدم _ لأي شيء آخر:

IconData iconFor(String condition) {
  return switch (condition) {
    'Sunny' => Icons.wb_sunny,
    'Cloudy' => Icons.cloud,
    _ => Icons.help_outline,
  };
}

تطابق الحالات نص الخادم تمامًا، بما في ذلك الأحرف الكبيرة: لن تطابق 'sunny' أبدًا Sunny. وتُبقي حالة _ التطبيق عاملًا إذا أرسل الخادم يومًا حالةً لم تخطط لها.

challenge icon

التحدي

متوسط

أضف الأيقونات:

  • طريقة iconFor: تكون Sunny هي Icons.wb_sunny، وتكون Cloudy هي Icons.cloud، وتكون Rainy هي Icons.umbrella، وتكون Snowy هي Icons.ac_unit، وأي قيمة أخرى تكون Icons.help_outline
  • أسفل المدينة، أيقونة الحالة الحالية، بحجم 96، وColors.orange
  • في بداية كل صف من صفوف التوقعات، أيقونة ذلك اليوم، ثم مسافة قدرها 16 بكسل

جرّب بنفسك

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:intl/intl.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)),
        const SizedBox(height: 32),
        for (final day in weather.forecast)
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 8),
            child: Row(
              children: [
                Expanded(
                  child: Text(
                    DateFormat('EEEE').format(day.date),
                    style: const TextStyle(fontSize: 18),
                  ),
                ),
                Text('${day.high}° / ${day.low}°', style: const TextStyle(fontSize: 18)),
              ],
            ),
          ),
      ],
    );
  }
}

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 عبر الإنترنت