Skip to content

Instantly share code, notes, and snippets.

@xsokev
Created May 18, 2018 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xsokev/d5839a0e93439c7c84a2406f54f67dab to your computer and use it in GitHub Desktop.
Save xsokev/d5839a0e93439c7c84a2406f54f67dab to your computer and use it in GitHub Desktop.
Flutter Weather Screen Design with Current Temperature and Forecast
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:fluids/plugins/weather/models/models.dart'; //custom data models
import 'package:fluids/utils/md_icons.dart'; //material design community icons
class CityForecast extends StatelessWidget {
final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
final String city;
final String state;
final Forecast forecast;
CityForecast({this.city, this.state, this.forecast});
@override
Widget build(BuildContext context) {
final int contentHgt = 240;
double imageHeight = MediaQuery.of(context).size.height - contentHgt;
return Stack(
children: <Widget>[
new Positioned(
child: Image.network(
weatherImage,
fit: BoxFit.cover,
),
height: imageHeight,
top: 0.0,
left: 0.0,
right: 0.0,
),
new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
),
backgroundColor: Colors.transparent,
body: new Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
_makeWeatherRow(context),
Container(
height: contentHgt.toDouble(),
color: Colors.white,
child: new SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_makeWeatherExtra(context),
Expanded(
child: AnimatedList(
key: _listKey,
initialItemCount: forecast.daily.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index, animation){
return _makeDay(context, animation, forecast.daily[index]);
},
),
)
],
),
),
)
],
),
),
],
);
}
_makeDay(BuildContext context, animation, Weather w){
return FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
child: new Container(
width: 120.0,
decoration: BoxDecoration(
border: Border(right: BorderSide(width: 1.0, color: Colors.black26)),
),
margin: EdgeInsets.symmetric(vertical: 10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(DateFormat('EEE').format(w.dateTime).toUpperCase()),
Expanded(
child: Icon(w.mcIcon, size: 40.0,),
),
Text('${w.temperatureMax.round()} / ${w.temperatureMin.round()}', style: Theme.of(context).textTheme.title,),
],
),
),
),
);
}
_makeWeatherRow(context) {
Weather current = forecast != null && forecast.currently != null ? forecast.currently : null;
return current == null ? Container() : Container(
color: Colors.black45,
padding: EdgeInsets.all(20.0),
child: new Column(
children: <Widget>[
new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(current.temperature.toStringAsFixed(0), style: Theme.of(context).textTheme.display2.copyWith(color: Colors.white),),
Icon(MDIcons.temperature_fahrenheit, color: Colors.white, size: 30.0,),
],
),
new Expanded(
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(right: 30.0),
child: Icon(current.mcIcon, color: Colors.white, size: 60.0,),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$city, $state'.toUpperCase(), style: Theme.of(context).textTheme.title.copyWith(color: Colors.white),),
Text(DateFormat('EEEEE, MMMM d').format(DateTime.now()).toUpperCase(), style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),),
],
)
],
),
_makeWeatherSummary(context),
],
),
);
}
_makeWeatherExtra(BuildContext context) {
Weather current = forecast != null && forecast.currently != null ? forecast.currently : null;
return current == null ? Container() : Container(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_makeExtraInfoStat(context, MDIcons.flag_variant_outline, '${current.windSpeed.round()} MPH'),
_makeExtraInfoStat(context, MDIcons.compass_outline, '${current.windDirection}'),
_makeExtraInfoStat(context, MDIcons.umbrella_outline, '${current.precipitationProbability.round()}%'),
],
),
),
Divider(),
],
),
);
}
_makeExtraInfoStat(BuildContext context, IconData icon, String info){
return Row(
children: <Widget>[
Icon(icon),
Text(info.toUpperCase(), style: Theme.of(context).textTheme.title,),
],
);
}
_makeWeatherSummary(BuildContext context) {
String summary = Utf8Codec().decode(forecast.dailySummary.codeUnits);
return Container(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 10.0),
child: Text(
summary,
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
),
),
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment