Skip to content

Commit b000099

Browse files
author
Ananthu Kanive
committed
add theme switch option
add humidity and wind speed data
1 parent a3ec94b commit b000099

File tree

10 files changed

+89
-64
lines changed

10 files changed

+89
-64
lines changed

ios/Flutter/Debug.xcconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
12
#include "Generated.xcconfig"

ios/Flutter/Release.xcconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
12
#include "Generated.xcconfig"

lib/main.dart

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_weather/src/screens/weather_screen.dart';
33
import 'package:bloc/bloc.dart';
44
import 'package:flutter_weather/src/themes.dart';
5+
import 'package:shared_preferences/shared_preferences.dart';
56

67
void main() {
78
BlocSupervisor().delegate = SimpleBlocDelegate();
8-
runApp(RootWidget());
9+
runApp(AppStateContainer(child: WeatherApp()));
910
}
1011

1112
class SimpleBlocDelegate extends BlocDelegate {
@@ -16,25 +17,19 @@ class SimpleBlocDelegate extends BlocDelegate {
1617
}
1718
}
1819

19-
class RootWidget extends StatelessWidget {
20-
@override
21-
Widget build(BuildContext context) {
22-
return AppStateContainer(child: WeatherApp());
23-
}
24-
}
25-
2620
class WeatherApp extends StatelessWidget {
2721
@override
2822
Widget build(BuildContext context) {
29-
return AppStateContainer(
30-
child: MaterialApp(
23+
return MaterialApp(
3124
title: 'Flutter Weather App',
3225
theme: AppStateContainer.of(context).theme,
3326
home: WeatherScreen(),
34-
));
27+
);
3528
}
3629
}
3730

31+
/// top level widget to hold application state
32+
/// state is passed down with an inherited widget
3833
class AppStateContainer extends StatefulWidget {
3934
final Widget child;
4035

@@ -51,7 +46,19 @@ class AppStateContainer extends StatefulWidget {
5146
}
5247

5348
class _AppStateContainerState extends State<AppStateContainer> {
54-
ThemeData _theme = Themes.light;
49+
ThemeData _theme = Themes.getTheme(Themes.DARK_THEME_CODE);
50+
51+
@override
52+
initState() {
53+
super.initState();
54+
SharedPreferences.getInstance().then((sharedPref) {
55+
int themeCode =
56+
sharedPref.getInt(Themes.SHARED_PREF_KEY) ?? Themes.DARK_THEME_CODE;
57+
setState(() {
58+
this._theme = Themes.getTheme(themeCode);
59+
});
60+
});
61+
}
5562

5663
@override
5764
Widget build(BuildContext context) {
@@ -64,9 +71,12 @@ class _AppStateContainerState extends State<AppStateContainer> {
6471

6572
ThemeData get theme => _theme;
6673

67-
updateTheme(ThemeData value) {
74+
updateTheme(int themeCode) {
6875
setState(() {
69-
_theme = value;
76+
_theme = Themes.getTheme(themeCode);
77+
});
78+
SharedPreferences.getInstance().then((sharedPref) {
79+
sharedPref.setInt(Themes.SHARED_PREF_KEY, themeCode);
7080
});
7181
}
7282
}

lib/src/screens/weather_screen.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ class _WeatherScreenState extends State<WeatherScreen>
195195
this._showCityChangeDialog();
196196
break;
197197
case OptionsMenu.nightMode:
198-
AppStateContainer.of(context).updateTheme(Themes.dark);
198+
AppStateContainer.of(context).updateTheme(Themes.DARK_THEME_CODE);
199199
break;
200200
case OptionsMenu.lightMode:
201-
AppStateContainer.of(context).updateTheme(Themes.light);
201+
AppStateContainer.of(context).updateTheme(Themes.LIGHT_THEME_CODE);
202202
break;
203203
}
204204
}

lib/src/themes.dart

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import 'package:flutter/material.dart';
22

33
class Themes {
4-
static final dark = ThemeData(
4+
static const SHARED_PREF_KEY = "theme_code";
5+
static const DARK_THEME_CODE = 0;
6+
static const LIGHT_THEME_CODE = 1;
7+
8+
static final _dark = ThemeData(
59
primarySwatch: MaterialColor(
610
Colors.black.value,
711
const <int, Color>{
@@ -19,7 +23,8 @@ class Themes {
1923
),
2024
accentColor: Colors.white,
2125
);
22-
static final light = ThemeData(
26+
27+
static final _light = ThemeData(
2328
primarySwatch: MaterialColor(
2429
Colors.white.value,
2530
const <int, Color>{
@@ -37,4 +42,12 @@ class Themes {
3742
),
3843
accentColor: Colors.black,
3944
);
45+
46+
static ThemeData getTheme(int code) {
47+
if(code == LIGHT_THEME_CODE){
48+
return _light;
49+
}
50+
return _dark;
51+
}
52+
4053
}

lib/src/widgets/forecast_horizontal_widget.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ForecastHorizontal extends StatelessWidget {
3030
padding: const EdgeInsets.only(left: 10, right: 10),
3131
child: Center(
3232
child: ValueTile(
33-
DateFormat('h aa').format(
33+
DateFormat('E, ha').format(
3434
DateTime.fromMillisecondsSinceEpoch(item.time * 1000)),
3535
'${item.temperature.celsius.round()}°',
3636
iconData: item.getIconData(),

lib/src/widgets/weather_widget.dart

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ class WeatherWidget extends StatelessWidget {
5454
color: AppStateContainer.of(context).theme.accentColor),
5555
),
5656
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
57-
ValueTile(
58-
"max", '${this.weather.maxTemperature.celsius.round()}°'),
57+
ValueTile("max", '${this.weather.maxTemperature.celsius.round()}°'),
5958
Padding(
6059
padding: const EdgeInsets.only(left: 20, right: 20),
6160
child: Center(
@@ -68,34 +67,41 @@ class WeatherWidget extends StatelessWidget {
6867
.withAlpha(50),
6968
)),
7069
),
71-
ValueTile(
72-
"min", '${this.weather.minTemperature.celsius.round()}°'),
70+
ValueTile("min", '${this.weather.minTemperature.celsius.round()}°'),
7371
]),
7472
Padding(
7573
child: Divider(
76-
color: AppStateContainer.of(context)
77-
.theme
78-
.accentColor
79-
.withAlpha(50),
74+
color:
75+
AppStateContainer.of(context).theme.accentColor.withAlpha(50),
8076
),
8177
padding: EdgeInsets.all(10),
8278
),
8379
ForecastHorizontal(weathers: weather.forecast),
8480
Padding(
8581
child: Divider(
86-
color: AppStateContainer.of(context)
87-
.theme
88-
.accentColor
89-
.withAlpha(50),
82+
color:
83+
AppStateContainer.of(context).theme.accentColor.withAlpha(50),
9084
),
9185
padding: EdgeInsets.all(10),
9286
),
9387
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
88+
ValueTile("wind speed", '${this.weather.windSpeed} m/s'),
89+
Padding(
90+
padding: const EdgeInsets.only(left: 20, right: 20),
91+
child: Center(
92+
child: Container(
93+
width: 1,
94+
height: 30,
95+
color: AppStateContainer.of(context)
96+
.theme
97+
.accentColor
98+
.withAlpha(50),
99+
)),
100+
),
94101
ValueTile(
95102
"sunrise",
96-
DateFormat('h:m a').format(
97-
DateTime.fromMillisecondsSinceEpoch(
98-
this.weather.sunrise * 1000))),
103+
DateFormat('h:m a').format(DateTime.fromMillisecondsSinceEpoch(
104+
this.weather.sunrise * 1000))),
99105
Padding(
100106
padding: const EdgeInsets.only(left: 20, right: 20),
101107
child: Center(
@@ -110,9 +116,21 @@ class WeatherWidget extends StatelessWidget {
110116
),
111117
ValueTile(
112118
"sunset",
113-
DateFormat('h:m a').format(
114-
DateTime.fromMillisecondsSinceEpoch(
115-
this.weather.sunset * 1000))),
119+
DateFormat('h:m a').format(DateTime.fromMillisecondsSinceEpoch(
120+
this.weather.sunset * 1000))),
121+
Padding(
122+
padding: const EdgeInsets.only(left: 20, right: 20),
123+
child: Center(
124+
child: Container(
125+
width: 1,
126+
height: 30,
127+
color: AppStateContainer.of(context)
128+
.theme
129+
.accentColor
130+
.withAlpha(50),
131+
)),
132+
),
133+
ValueTile("humidity", '${this.weather.humidity}%'),
116134
]),
117135
],
118136
),

pubspec.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ packages:
130130
url: "https://pub.dartlang.org"
131131
source: hosted
132132
version: "0.22.0"
133+
shared_preferences:
134+
dependency: "direct main"
135+
description:
136+
name: shared_preferences
137+
url: "https://pub.dartlang.org"
138+
source: hosted
139+
version: "0.5.3+1"
133140
sky_engine:
134141
dependency: transitive
135142
description: flutter
@@ -193,3 +200,4 @@ packages:
193200
version: "2.0.8"
194201
sdks:
195202
dart: ">=2.2.0 <3.0.0"
203+
flutter: ">=1.5.0 <2.0.0"

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies:
2424
bloc: ^0.13.0
2525
flutter_bloc: ^0.13.0
2626
intl: ^0.15.8
27+
shared_preferences: 0.5.3+1
2728

2829
# The following adds the Cupertino Icons font to your application.
2930
# Use with the CupertinoIcons class for iOS style icons.

test/widget_test.dart

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,3 @@
1-
// This is a basic Flutter widget test.
2-
//
3-
// To perform an interaction with a widget in your test, use the WidgetTester
4-
// utility that Flutter provides. For example, you can send tap and scroll
5-
// gestures. You can also use WidgetTester to find child widgets in the widget
6-
// tree, read text, and verify that the values of widget properties are correct.
7-
8-
import 'package:flutter/material.dart';
9-
import 'package:flutter_test/flutter_test.dart';
10-
11-
import 'package:flutter_weather/main.dart';
12-
131
void main() {
14-
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15-
// Build our app and trigger a frame.
16-
await tester.pumpWidget(RootWidget());
17-
18-
// Verify that our counter starts at 0.
19-
expect(find.text('0'), findsOneWidget);
20-
expect(find.text('1'), findsNothing);
21-
22-
// Tap the '+' icon and trigger a frame.
23-
await tester.tap(find.byIcon(Icons.add));
24-
await tester.pump();
252

26-
// Verify that our counter has incremented.
27-
expect(find.text('0'), findsNothing);
28-
expect(find.text('1'), findsOneWidget);
29-
});
303
}

0 commit comments

Comments
 (0)