@@ -3,7 +3,10 @@ package com.piotrprus.weathercard
3
3
import android.os.Bundle
4
4
import androidx.activity.ComponentActivity
5
5
import androidx.activity.compose.setContent
6
+ import androidx.activity.viewModels
6
7
import androidx.compose.foundation.Canvas
8
+ import androidx.compose.foundation.Image
9
+ import androidx.compose.foundation.background
7
10
import androidx.compose.foundation.isSystemInDarkTheme
8
11
import androidx.compose.foundation.layout.*
9
12
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -12,119 +15,128 @@ import androidx.compose.material.icons.Icons
12
15
import androidx.compose.material.icons.filled.Air
13
16
import androidx.compose.material.icons.filled.Water
14
17
import androidx.compose.material.icons.filled.WbSunny
15
- import androidx.compose.runtime.Composable
16
- import androidx.compose.runtime.mutableStateOf
17
- import androidx.compose.runtime.remember
18
+ import androidx.compose.runtime.*
19
+ import androidx.compose.runtime.livedata.observeAsState
18
20
import androidx.compose.ui.Alignment
19
21
import androidx.compose.ui.Modifier
20
22
import androidx.compose.ui.geometry.Offset
21
23
import androidx.compose.ui.graphics.Color
22
24
import androidx.compose.ui.graphics.nativeCanvas
23
25
import androidx.compose.ui.platform.LocalDensity
24
- import androidx.compose.ui.tooling.preview.Preview
26
+ import androidx.compose.ui.res.painterResource
27
+ import androidx.compose.ui.text.font.FontWeight
25
28
import androidx.compose.ui.unit.dp
26
29
import com.piotrprus.weathercard.ui.theme.WeatherCardTheme
27
30
28
31
class MainActivity : ComponentActivity () {
32
+ private val forecastMockState = mutableStateListOf(
33
+ WeatherItem (date = " Mon, 8:00 AM, Cloudy" , temperature = 12 , 30 , 2 , R .drawable.cloudy),
34
+ WeatherItem (date = " Mon, 9:00 AM, Cloudy" , temperature = 14 , 60 , 3 , R .drawable.cloudy),
35
+ WeatherItem (date = " Mon, 10:00 AM, Mostly cloudy" , temperature = 15 , 80 , 5 , R .drawable.rain),
36
+ WeatherItem (date = " Mon, 11:00 AM, Mostly sunny" , temperature = 15 , 30 , 2 , R .drawable.sunny),
37
+ WeatherItem (date = " Mon, 12:00 PM, Mostly sunny" , temperature = 18 , 20 , 1 , R .drawable.sunny),
38
+ WeatherItem (date = " Mon, 1:00 PM, Sunny" , temperature = 20 , 0 , 1 , R .drawable.sunny),
39
+ WeatherItem (date = " Mon, 2:00 PM, Sunny" , temperature = 20 , 0 , 2 , R .drawable.sunny),
40
+ WeatherItem (date = " Mon, 3:00 PM, Sunny" , temperature = 19 , 0 , 2 , R .drawable.sunny),
41
+ WeatherItem (date = " Mon, 4:00 PM, Sunny" , temperature = 19 , 0 , 2 , R .drawable.sunny),
42
+ WeatherItem (date = " Mon, 5:00 PM, Sunny" , temperature = 17 , 0 , 3 , R .drawable.sunny),
43
+ WeatherItem (date = " Mon, 6:00 PM, Heavy showers" , temperature = 16 , 80 , 7 , R .drawable.rain),
44
+ WeatherItem (date = " Mon, 7:00 PM, Heavy showers" , temperature = 15 , 90 , 9 , R .drawable.rain),
45
+ )
46
+
47
+ private val viewModel: MainViewModel by viewModels()
48
+
29
49
override fun onCreate (savedInstanceState : Bundle ? ) {
30
50
super .onCreate(savedInstanceState)
31
51
setContent {
32
52
WeatherCardTheme {
33
53
// A surface container using the 'background' color from the theme
34
54
Surface (color = MaterialTheme .colors.background) {
35
- WeatherCard (
36
- WeatherItem (
37
- date = " MON 8:32PM" ,
38
- temperature = 21 ,
39
- precipitation = 2 ,
40
- windSpeed = 5
41
- )
42
- )
55
+ val selectedValue: Int by viewModel.selected.observeAsState(initial = 0 )
56
+ WeatherCard (forecastMockState, selectedValue) {
57
+ viewModel.onValueChanged(it)
58
+ }
43
59
}
44
60
}
45
61
}
46
62
}
47
63
}
48
64
49
- @Preview
50
- @Composable
51
- fun PreviewWeatherCard () {
52
- WeatherCard (
53
- WeatherItem (
54
- date = " MON, 8.32PM" ,
55
- temperature = 21 ,
56
- precipitation = 2 ,
57
- windSpeed = 5
58
- )
59
- )
60
- }
61
-
62
-
63
65
@Composable
64
- private fun WeatherCard (data : WeatherItem ) {
66
+ private fun WeatherCard (list : List <WeatherItem >, selectedValue : Int , onValueChange : (Int ) -> Unit ) {
67
+ val item by remember(selectedValue, list) {
68
+ derivedStateOf { list[selectedValue] }
69
+ }
65
70
Card (
66
71
modifier = Modifier
67
72
.fillMaxWidth()
68
- .padding(8 .dp),
73
+ .padding(12 .dp),
69
74
elevation = 4 .dp,
70
75
shape = RoundedCornerShape (12 .dp),
71
76
) {
72
77
Column (modifier = Modifier .padding(12 .dp)) {
73
- Text (text = " Hong Kong" , style = MaterialTheme .typography.h4)
74
- Spacer (modifier = Modifier .height(8 .dp))
75
- Text (text = data.date, style = MaterialTheme .typography.subtitle1)
76
- Spacer (modifier = Modifier .height(8 .dp))
77
- Row (
78
- modifier = Modifier .fillMaxWidth(),
79
- horizontalArrangement = Arrangement .SpaceEvenly ,
80
- verticalAlignment = Alignment .CenterVertically
81
- ) {
82
- Row {
83
- Text (text = data.temperature.toString(), style = MaterialTheme .typography.h1)
84
- Text (
85
- modifier = Modifier .padding(top = 10 .dp),
86
- text = " °C" ,
87
- style = MaterialTheme .typography.h3
88
- )
89
- }
90
- Icon (
91
- modifier = Modifier .size(60 .dp),
92
- imageVector = Icons .Default .WbSunny ,
93
- contentDescription = " Sun icon" ,
94
- tint = MaterialTheme .colors.onSurface
95
- )
96
- }
97
- Spacer (modifier = Modifier .height(8 .dp))
98
- Row (
99
- modifier = Modifier .fillMaxWidth(),
100
- horizontalArrangement = Arrangement .SpaceEvenly
101
- ) {
102
- Row (verticalAlignment = Alignment .CenterVertically ) {
103
- Icon (imageVector = Icons .Default .Water , contentDescription = " Water icon" )
104
- Spacer (modifier = Modifier .width(4 .dp))
105
- Text (
106
- text = " ${data.precipitation} % Precipitation" ,
107
- style = MaterialTheme .typography.subtitle2
108
- )
109
- }
110
- Row (verticalAlignment = Alignment .CenterVertically ) {
111
- Icon (imageVector = Icons .Default .Air , contentDescription = " Air icon" )
112
- Spacer (modifier = Modifier .width(4 .dp))
113
- Text (
114
- text = " ${data.windSpeed} km/h Winds" ,
115
- style = MaterialTheme .typography.subtitle2
116
- )
117
- }
118
- }
119
- ForecastSlider ()
78
+ MeasurementView (item)
79
+ ForecastSlider (
80
+ list.map { it.date },
81
+ onValueChange = { onValueChange(it) },
82
+ value = selectedValue.toFloat()
83
+ )
84
+ }
85
+ }
86
+ }
87
+
88
+ @Composable
89
+ private fun MeasurementView (data : WeatherItem ) {
90
+ Text (text = " Hong Kong" , style = MaterialTheme .typography.h5)
91
+ Spacer (modifier = Modifier .height(8 .dp))
92
+ Text (text = data.date, style = MaterialTheme .typography.body2.copy(color = Color .Gray ))
93
+ Spacer (modifier = Modifier .height(8 .dp))
94
+ Row (
95
+ modifier = Modifier .fillMaxWidth(),
96
+ horizontalArrangement = Arrangement .SpaceEvenly ,
97
+ verticalAlignment = Alignment .CenterVertically
98
+ ) {
99
+ Row {
100
+ Text (text = data.temperature.toString(), style = MaterialTheme .typography.h1)
101
+ Text (
102
+ modifier = Modifier .padding(top = 10 .dp),
103
+ text = " °C" ,
104
+ style = MaterialTheme .typography.h3
105
+ )
106
+ }
107
+ Image (
108
+ modifier = Modifier .size(100 .dp),
109
+ painter = painterResource(id = data.icon),
110
+ contentDescription = " Weather icon"
111
+ )
112
+ }
113
+ Spacer (modifier = Modifier .height(8 .dp))
114
+ Row (
115
+ modifier = Modifier .fillMaxWidth(),
116
+ horizontalArrangement = Arrangement .SpaceEvenly
117
+ ) {
118
+ Row (verticalAlignment = Alignment .CenterVertically ) {
119
+ Icon (imageVector = Icons .Default .Water , contentDescription = " Water icon" )
120
+ Spacer (modifier = Modifier .width(4 .dp))
121
+ Text (
122
+ text = " ${data.precipitation} % Precipitation" ,
123
+ style = MaterialTheme .typography.body2.copy(color = Color .Gray )
124
+ )
125
+ }
126
+ Row (verticalAlignment = Alignment .CenterVertically ) {
127
+ Icon (imageVector = Icons .Default .Air , contentDescription = " Air icon" )
128
+ Spacer (modifier = Modifier .width(4 .dp))
129
+ Text (
130
+ text = " ${data.windSpeed} km/h Winds" ,
131
+ style = MaterialTheme .typography.body2.copy(color = Color .Gray )
132
+ )
120
133
}
121
134
}
122
135
}
123
136
124
137
@Composable
125
- fun ForecastSlider () {
126
- val (sliderValue, setSliderValue) = remember { mutableStateOf(6f ) }
127
- val steps = 11
138
+ fun ForecastSlider (dates : List <String >, value : Float , onValueChange : (Int ) -> Unit ) {
139
+ val (sliderValue, setSliderValue) = remember { mutableStateOf(value) }
128
140
val drawPadding = with (LocalDensity .current) { 10 .dp.toPx() }
129
141
val textSize = with (LocalDensity .current) { 10 .dp.toPx() }
130
142
val lineHeightDp = 10 .dp
@@ -147,17 +159,17 @@ fun ForecastSlider() {
147
159
)
148
160
) {
149
161
val yStart = 0f
150
- val distance = (size.width.minus(2 * drawPadding)).div(steps + 1 )
151
- ( 0 .. steps.plus( 1 )).forEach { step ->
162
+ val distance = (size.width.minus(2 * drawPadding)).div(dates.size.minus( 1 ) )
163
+ dates.forEachIndexed { index, step ->
152
164
drawLine(
153
165
color = Color .DarkGray ,
154
- start = Offset (x = drawPadding + step .times(distance), y = yStart),
155
- end = Offset (x = drawPadding + step .times(distance), y = lineHeightPx)
166
+ start = Offset (x = drawPadding + index .times(distance), y = yStart),
167
+ end = Offset (x = drawPadding + index .times(distance), y = lineHeightPx)
156
168
)
157
- if (step .rem(3 ) == 0 ) {
169
+ if (index .rem(3 ) == 0 ) {
158
170
this .drawContext.canvas.nativeCanvas.drawText(
159
- " 12.30 " ,
160
- drawPadding + step .times(distance),
171
+ step ,
172
+ drawPadding + index .times(distance),
161
173
size.height,
162
174
textPaint
163
175
)
@@ -167,17 +179,18 @@ fun ForecastSlider() {
167
179
Slider (
168
180
modifier = Modifier .fillMaxWidth(),
169
181
value = sliderValue,
170
- valueRange = 0f .. 12f ,
171
- steps = steps ,
182
+ valueRange = 0f .. dates.size.minus( 1 ).toFloat() ,
183
+ steps = dates.size.minus( 2 ) ,
172
184
colors = customSliderColors(),
173
185
onValueChange = {
174
186
setSliderValue(it)
187
+ onValueChange(it.toInt())
175
188
})
176
189
}
177
190
}
178
191
179
192
@Composable
180
193
private fun customSliderColors (): SliderColors = SliderDefaults .colors(
181
194
activeTickColor = Color .Transparent ,
182
- inactiveTickColor = Color .Transparent
183
- )
195
+ // inactiveTickColor = Color.Transparent
196
+ )
0 commit comments