Skip to content
Snippets Groups Projects
Unverified Commit f5eee4a2 authored by AC5636's avatar AC5636 :ghost:
Browse files

Add exercise solution for ex12

parent 1bcd179a
No related branches found
No related tags found
No related merge requests found
......@@ -4,4 +4,5 @@ Exercise 10: Favourite Cities
Exercise 11: Golf Courses
![Golf Courses](screenshots/ex11.png)
<!-- Exercise 12: Golf Courses in a Map with Clustering -->
Exercise 12: Golf Courses in a Map with Clustering
![Golf Courses in a Map with Clustering](screenshots/ex12.png)
......@@ -6,6 +6,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.clustering.ClusterItem
import kotlinx.coroutines.launch
class GolfCoursesViewModel: ViewModel() {
......@@ -68,14 +69,23 @@ data class Course(
val web: String,
val image: String,
val text: String
){
fun getPosition(): LatLng {
): ClusterItem {
override fun getPosition(): LatLng {
return LatLng(lat, lng)
}
fun getImageURL(): String {
println("${golfCoursesApiBaseURL}${image}")
return "${golfCoursesApiBaseURL}${image}"
}
override fun getTitle(): String =
"$course - $type"
override fun getSnippet(): String =
text
override fun getZIndex(): Float =
1F
}
// Sample api response
//{
......
......@@ -25,6 +25,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Place
import androidx.compose.material3.Card
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedCard
......@@ -53,10 +54,13 @@ import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.clustering.ClusterItem
import com.google.maps.android.compose.GoogleMap
import com.google.maps.android.compose.MapsComposeExperimentalApi
import com.google.maps.android.compose.Marker
import com.google.maps.android.compose.MarkerInfoWindow
import com.google.maps.android.compose.MarkerState
import com.google.maps.android.compose.clustering.Clustering
import com.google.maps.android.compose.rememberCameraPositionState
import compose.icons.TablerIcons
import compose.icons.tablericons.ExternalLink
......@@ -84,6 +88,7 @@ class MainActivity : ComponentActivity() {
}
@OptIn(MapsComposeExperimentalApi::class)
@Composable
fun App(golfCourses: List<Course>) {
var configuration = LocalConfiguration.current
......@@ -97,66 +102,68 @@ fun App(golfCourses: List<Course>) {
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState
) {
for (course in golfCourses) {
val painter = rememberAsyncImagePainter(model = course.getImageURL())
Clustering(items=golfCourses)
MarkerInfoWindow(
state = MarkerState(position = course.getPosition()),
title = course.course,
snippet = course.text,
) {
OutlinedCard(modifier = Modifier
.fillMaxWidth(((configuration.screenWidthDp * 0.85) / configuration.screenWidthDp).toFloat())
.heightIn(max = (configuration.screenHeightDp * 0.75).dp)
) {
Column(
modifier = Modifier
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
// Image(painter = painter, contentDescription = null)
Text(
text = "${course.course} - ${course.type}",
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 6.dp)
)
Column {
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
Icon(
imageVector = TablerIcons.PhoneOutgoing,
contentDescription = null
)
Text(text = course.phone)
}
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
Icon(imageVector = TablerIcons.MapPin, contentDescription = null)
Text(text = course.address)
}
Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
Icon(
imageVector = TablerIcons.ExternalLink,
contentDescription = null
)
Text(text = course.web)
}
}
Text(
text = course.text,
modifier = Modifier
.fillMaxWidth()
.verticalScroll(
rememberScrollState()
)
)
}
}
}
}
// for (course in golfCourses) {
// val painter = rememberAsyncImagePainter(model = course.getImageURL())
//
// MarkerInfoWindow(
// state = MarkerState(position = course.getPosition()),
// title = course.course,
// snippet = course.text,
// ) {
// OutlinedCard(modifier = Modifier
// .fillMaxWidth(((configuration.screenWidthDp * 0.85) / configuration.screenWidthDp).toFloat())
// .heightIn(max = (configuration.screenHeightDp * 0.75).dp)
// ) {
// Column(
// modifier = Modifier
// .padding(16.dp),
// verticalArrangement = Arrangement.spacedBy(12.dp)
// ) {
//// Image(painter = painter, contentDescription = null)
// Text(
// text = "${course.course} - ${course.type}",
// style = MaterialTheme.typography.titleLarge,
// textAlign = TextAlign.Center,
// modifier = Modifier
// .fillMaxWidth()
// .padding(bottom = 6.dp)
// )
//
// Column {
// Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
// Icon(
// imageVector = TablerIcons.PhoneOutgoing,
// contentDescription = null
// )
// Text(text = course.phone)
// }
// Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
// Icon(imageVector = TablerIcons.MapPin, contentDescription = null)
// Text(text = course.address)
// }
// Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
// Icon(
// imageVector = TablerIcons.ExternalLink,
// contentDescription = null
// )
// Text(text = course.web)
// }
// }
//
// Text(
// text = course.text,
// modifier = Modifier
// .fillMaxWidth()
// .verticalScroll(
// rememberScrollState()
// )
// )
// }
// }
// }
// }
}
}
......
E10FavouriteCities/screenshots/ex12.png

465 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment