Skip to content

Instantly share code, notes, and snippets.

@Craftplacer
Last active April 20, 2024 10:35
Show Gist options
  • Save Craftplacer/2fcbb75286c6e4f6b25f52e44f39438a to your computer and use it in GitHub Desktop.
Save Craftplacer/2fcbb75286c6e4f6b25f52e44f39438a to your computer and use it in GitHub Desktop.
Weather app
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
void main() => runApp(const WeatherApp());
class WeatherApp extends StatelessWidget {
const WeatherApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
// The new monochrome scheme is not available on DartPad yet
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.white,
),
cardTheme: CardTheme(
color: Colors.white,
shadowColor: Colors.transparent,
elevation: 0.0,
),
),
home: Scaffold(
body: Stack(
children: [
Positioned.fill(
child: Image.network(
'https://images.unsplash.com/photo-1521206698660-5e077ff6f9c8',
fit: BoxFit.cover,
alignment: Alignment.bottomCenter,
),
),
Align(
alignment: Alignment(0, -.75),
child: WeatherCard(
forecast: Forecast(
temperature: 30.0,
location: 'New York City',
weather: Weather.lightSnow,
),
),
),
],
),
),
);
}
}
/// A card showing information for a [Forecast].
class WeatherCard extends StatelessWidget {
final Forecast forecast;
const WeatherCard({super.key, required this.forecast});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
WeatherIcon(forecast.weather, size: 64.0),
const SizedBox(height: 16),
Text(
'${forecast.temperature.round()}°',
style: theme.textTheme.displayLarge!.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Text(
forecast.weather.description,
style: theme.textTheme.titleLarge,
),
Text(
forecast.location,
style: theme.textTheme.bodyMedium,
),
],
),
),
);
}
}
class WeatherIcon extends StatelessWidget {
final Weather weather;
final double? size;
const WeatherIcon(this.weather, {super.key, this.size});
@override
Widget build(BuildContext context) {
final size = this.size ?? 24.0;
return SvgPicture(
SvgStringLoader(weather.svg),
width: size,
height: size,
);
}
}
/// Class representing a forecast.
class Forecast {
/// The temperature in Fahrenheit.
final double temperature;
/// The current weather condition.
final Weather weather;
/// The location.
final String location;
const Forecast({
required this.temperature,
required this.weather,
required this.location,
});
}
enum Weather {
// TODO: Add more weather conditions
lightSnow;
// FIXME: needs to be replaced with a method if it is supposed to be localized later
String get description {
return switch (this) {
Weather.lightSnow => 'Light snow',
};
}
/// As of April 2024, there is no official Material Symbols package for Flutter.
String get svg {
return switch (this) {
Weather.lightSnow =>
'<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M160-410H80q-17 0-28.5-11.5T40-450q0-17 11.5-28.5T80-490h80q17 0 28.5 11.5T200-450q0 17-11.5 28.5T160-410Zm122-238q-11 11-28 11t-28-11l-57-57q-12-12-12-28t12-28q12-11 28-11.5t28 11.5l57 57q11 11 11.5 27.5T282-648Zm-42 448q-21 0-35.5-14.5T190-250q0-21 14.5-35.5T240-300q21 0 35.5 14.5T290-250q0 21-14.5 35.5T240-200Zm80-210q-17 0-28.5-11.5T280-450q0-83 58.5-141.5T480-650q83 0 141.5 58.5T680-450q0 17-11.5 28.5T640-410H320Zm40 370q-21 0-35.5-14.5T310-90q0-21 14.5-35.5T360-140q21 0 35.5 14.5T410-90q0 21-14.5 35.5T360-40Zm120-160q-21 0-35.5-14.5T430-250q0-21 14.5-35.5T480-300q21 0 35.5 14.5T530-250q0 21-14.5 35.5T480-200Zm0-530q-17 0-28.5-11.5T440-770v-80q0-17 11.5-28.5T480-890q17 0 28.5 11.5T520-850v80q0 17-11.5 28.5T480-730ZM600-40q-21 0-35.5-14.5T550-90q0-21 14.5-35.5T600-140q21 0 35.5 14.5T650-90q0 21-14.5 35.5T600-40Zm78-608q-12-12-12-28t12-28l57-57q11-11 27.5-11.5T791-761q11 11 11 28t-11 28l-57 57q-11 11-27.5 11T678-648Zm42 448q-21 0-35.5-14.5T670-250q0-21 14.5-35.5T720-300q21 0 35.5 14.5T770-250q0 21-14.5 35.5T720-200Zm80-210q-17 0-28.5-11.5T760-450q0-17 11.5-28.5T800-490h80q17 0 28.5 11.5T920-450q0 17-11.5 28.5T880-410h-80Z"/></svg>',
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment