Created
August 21, 2023 00:42
-
-
Save BlakeBarrett/58ce9d62e510ee726b035143e4941d7e to your computer and use it in GitHub Desktop.
JSON USER DATA EXAMPLE: Fake Users JSON array generated by ChatGPT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"id": 1, | |
"first_name": "Alice", | |
"last_name": "Smith", | |
"email": "[email protected]", | |
"age": 28, | |
"last_login_date": "2023-08-09T10:30:00", | |
"friends_user_ids": [2, 3, 5, 7], | |
"favorite_animal": "Dog", | |
"least_favorite_smell": "Durian", | |
"hobbies": ["Painting", "Hiking"], | |
"birthplace": "Cityville", | |
"favorite_color": "Purple", | |
"unread_messages": 3, | |
"has_pets": true, | |
"shoe_size": 7.5, | |
"coffee_preference": "Black", | |
"dream_destination": "Bora Bora", | |
"music_genre": "Indie Rock", | |
"is_vegan": false, | |
"fitness_level": "Intermediate", | |
"lucky_number": 17 | |
}, | |
{ | |
"id": 2, | |
"first_name": "Bob", | |
"last_name": "Johnson", | |
"email": "[email protected]", | |
"age": 35, | |
"last_login_date": "2023-08-08T15:20:00", | |
"friends_user_ids": [1, 4, 8], | |
"favorite_animal": "Cat", | |
"least_favorite_smell": "Sulfur", | |
"hobbies": ["Reading", "Gardening"], | |
"birthplace": "Villageville", | |
"favorite_color": "Blue", | |
"unread_messages": 0, | |
"has_pets": true, | |
"shoe_size": 9.0, | |
"coffee_preference": "Latte", | |
"dream_destination": "Paris", | |
"music_genre": "Classical", | |
"is_vegan": true, | |
"fitness_level": "Beginner", | |
"lucky_number": 5 | |
}, | |
{ | |
"id": 3, | |
"first_name": "Charlie", | |
"last_name": "Brown", | |
"email": "[email protected]", | |
"age": 22, | |
"last_login_date": "2023-08-09T08:45:00", | |
"friends_user_ids": [1, 5, 9], | |
"favorite_animal": "Elephant", | |
"least_favorite_smell": "Fish", | |
"hobbies": ["Cooking", "Playing Guitar"], | |
"birthplace": "Townsville", | |
"favorite_color": "Green", | |
"unread_messages": 10, | |
"has_pets": false, | |
"shoe_size": 8.5, | |
"coffee_preference": "Cappuccino", | |
"dream_destination": "Tokyo", | |
"music_genre": "Pop", | |
"is_vegan": false, | |
"fitness_level": "Advanced", | |
"lucky_number": 12 | |
}, | |
{ | |
"id": 4, | |
"first_name": "David", | |
"last_name": "Lee", | |
"email": "[email protected]", | |
"age": 31, | |
"last_login_date": "2023-08-07T18:10:00", | |
"friends_user_ids": [2, 8, 10], | |
"favorite_animal": "Lion", | |
"least_favorite_smell": "Garlic", | |
"hobbies": ["Soccer", "Photography"], | |
"birthplace": "Countryville", | |
"favorite_color": "Yellow", | |
"unread_messages": 5, | |
"has_pets": true, | |
"shoe_size": 10.5, | |
"coffee_preference": "Espresso", | |
"dream_destination": "New York", | |
"music_genre": "Rock", | |
"is_vegan": false, | |
"fitness_level": "Intermediate", | |
"lucky_number": 9 | |
}, | |
{ | |
"id": 5, | |
"first_name": "Eve", | |
"last_name": "Williams", | |
"email": "[email protected]", | |
"age": 27, | |
"last_login_date": "2023-08-09T12:05:00", | |
"friends_user_ids": [1, 3, 9, 11], | |
"favorite_animal": "Dolphin", | |
"least_favorite_smell": "Onion", | |
"hobbies": ["Yoga", "Traveling"], | |
"birthplace": "Seaville", | |
"favorite_color": "Turquoise", | |
"unread_messages": 8, | |
"has_pets": true, | |
"shoe_size": 8.0, | |
"coffee_preference": "Mocha", | |
"dream_destination": "Maldives", | |
"music_genre": "Electronic", | |
"is_vegan": true, | |
"fitness_level": "Advanced", | |
"lucky_number": 3 | |
}, | |
{ | |
"id": 6, | |
"first_name": "Frank", | |
"last_name": "Davis", | |
"email": "[email protected]", | |
"age": 45, | |
"last_login_date": "2023-08-08T09:40:00", | |
"friends_user_ids": [12, 13, 14], | |
"favorite_animal": "Giraffe", | |
"least_favorite_smell": "Vinegar", | |
"hobbies": ["Golf", "Painting"], | |
"birthplace": "Mountainville", | |
"favorite_color": "Orange", | |
"unread_messages": 2, | |
"has_pets": false, | |
"shoe_size": 11.0, | |
"coffee_preference": "Americano", | |
"dream_destination": "Switzerland", | |
"music_genre": "Jazz", | |
"is_vegan": false, | |
"fitness_level": "Beginner", | |
"lucky_number": 8 | |
}, | |
{ | |
"id": 7, | |
"first_name": "Grace", | |
"last_name": "Martinez", | |
"email": "[email protected]", | |
"age": 29, | |
"last_login_date": "2023-08-09T16:15:00", | |
"friends_user_ids": [1, 15, 16], | |
"favorite_animal": "Penguin", | |
"least_favorite_smell": "Cabbage", | |
"hobbies": ["Singing", "Cooking"], | |
"birthplace": "Snowville", | |
"favorite_color": "White", | |
"unread_messages": 1, | |
"has_pets": true, | |
"shoe_size": 6.5, | |
"coffee_preference": "Latte", | |
"dream_destination": "Hawaii", | |
"music_genre": "Reggae", | |
"is_vegan": true, | |
"fitness_level": "Intermediate", | |
"lucky_number": 13 | |
}, | |
{ | |
"id": 8, | |
"first_name": "Henry", | |
"last_name": "Taylor", | |
"email": "[email protected]", | |
"age": 32, | |
"last_login_date": "2023-08-08T13:30:00", | |
"friends_user_ids": [2, 4, 9, 17], | |
"favorite_animal": "Tiger", | |
"least_favorite_smell": "Mold", | |
"hobbies": ["Running", "Chess"], | |
"birthplace": "Desertville", | |
"favorite_color": "Red", | |
"unread_messages": 12, | |
"has_pets": true, | |
"shoe_size": 10.0, | |
"coffee_preference": "Cappuccino", | |
"dream_destination": "Australia", | |
"music_genre": "Country", | |
"is_vegan": false, | |
"fitness_level": "Advanced", | |
"lucky_number": 21 | |
}, | |
{ | |
"id": 9, | |
"first_name": "Ivy", | |
"last_name": "Anderson", | |
"email": "[email protected]", | |
"age": 24, | |
"last_login_date": "2023-08-09T07:55:00", | |
"friends_user_ids": [3, 5, 8, 18], | |
"favorite_animal": "Kangaroo", | |
"least_favorite_smell": "Smoked Fish", | |
"hobbies": ["Dancing", "Biking"], | |
"birthplace": "Jungleville", | |
"favorite_color": "Yellow", | |
"unread_messages": 6, | |
"has_pets": true, | |
"shoe_size": 8.0, | |
"coffee_preference": "Espresso", | |
"dream_destination": "Brazil", | |
"music_genre": "Hip Hop", | |
"is_vegan": true, | |
"fitness_level": "Beginner", | |
"lucky_number": 6 | |
}, | |
{ | |
"id": 10, | |
"first_name": "Jack", | |
"last_name": "Moore", | |
"email": "[email protected]", | |
"age": 30, | |
"last_login_date": "2023-08-07T21:20:00", | |
"friends_user_ids": [4, 7, 9, 19], | |
"favorite_animal": "Horse", | |
"least_favorite_smell": "Burnt Rubber", | |
"hobbies": ["Photography", "Travelling"], | |
"birthplace": "Farmville", | |
"favorite_color": "Brown", | |
"unread_messages": 9, | |
"has_pets": true, | |
"shoe_size": 10.5, | |
"coffee_preference": "Black", | |
"dream_destination": "New Zealand", | |
"music_genre": "Alternative", | |
"is_vegan": false, | |
"fitness_level": "Intermediate", | |
"lucky_number": 11 | |
}, | |
{ | |
"id": 11, | |
"first_name": "Karen", | |
"last_name": "Jackson", | |
"email": "[email protected]", | |
"age": 26, | |
"last_login_date": "2023-08-09T14:50:00", | |
"friends_user_ids": [5, 10, 20], | |
"favorite_animal": "Panda", | |
"least_favorite_smell": "Rotting Fruit", | |
"hobbies": ["Yoga", "Reading"], | |
"birthplace": "Cityville", | |
"favorite_color": "Pink", | |
"unread_messages": 4, | |
"has_pets": false, | |
"shoe_size": 7.0, | |
"coffee_preference": "Mocha", | |
"dream_destination": "Thailand", | |
"music_genre": "R&B", | |
"is_vegan": true, | |
"fitness_level": "Advanced", | |
"lucky_number": 15 | |
}, | |
{ | |
"id": 12, | |
"first_name": "Liam", | |
"last_name": "Garcia", | |
"email": "[email protected]", | |
"age": 21, | |
"last_login_date": "2023-08-08T08:00:00", | |
"friends_user_ids": [6, 13, 15], | |
"favorite_animal": "Sloth", | |
"least_favorite_smell": "Dirty Socks", | |
"hobbies": ["Gaming", "Cooking"], | |
"birthplace": "Villageville", | |
"favorite_color": "Black", | |
"unread_messages": 7, | |
"has_pets": true, | |
"shoe_size": 9.5, | |
"coffee_preference": "Latte", | |
"dream_destination": "Greece", | |
"music_genre": "Metal", | |
"is_vegan": false, | |
"fitness_level": "Beginner", | |
"lucky_number": 14 | |
}, | |
{ | |
"id": 13, | |
"first_name": "Mia", | |
"last_name": "Rodriguez", | |
"email": "[email protected]", | |
"age": 33, | |
"last_login_date": "2023-08-09T11:40:00", | |
"friends_user_ids": [6, 12, 14, 16], | |
"favorite_animal": "Owl", | |
"least_favorite_smell": "Stale Beer", | |
"hobbies": ["Singing", "Painting"], | |
"birthplace": "Countryville", | |
"favorite_color": "Blue", | |
"unread_messages": 5, | |
"has_pets": true, | |
"shoe_size": 8.5, | |
"coffee_preference": "Cappuccino", | |
"dream_destination": "Italy", | |
"music_genre": "Pop", | |
"is_vegan": true, | |
"fitness_level": "Intermediate", | |
"lucky_number": 8 | |
}, | |
{ | |
"id": 14, | |
"first_name": "Noah", | |
"last_name": "Martinez", | |
"email": "[email protected]", | |
"age": 40, | |
"last_login_date": "2023-08-08T17:55:00", | |
"friends_user_ids": [6, 13, 15], | |
"favorite_animal": "Wolf", | |
"least_favorite_smell": "Mothballs", | |
"hobbies": ["Running", "Cooking"], | |
"birthplace": "Cityville", | |
"favorite_color": "Green", | |
"unread_messages": 2, | |
"has_pets": false, | |
"shoe_size": 10.0, | |
"coffee_preference": "Espresso", | |
"dream_destination": "Australia", | |
"music_genre": "Rock", | |
"is_vegan": false, | |
"fitness_level": "Advanced", | |
"lucky_number": 19 | |
}, | |
{ | |
"id": 15, | |
"first_name": "Olivia", | |
"last_name": "Thompson", | |
"email": "[email protected]", | |
"age": 29, | |
"last_login_date": "2023-08-09T10:15:00", | |
"friends_user_ids": [7, 13, 14, 17], | |
"favorite_animal": "Duck", | |
"least_favorite_smell": "Wet Dog", | |
"hobbies": ["Soccer", "Gardening"], | |
"birthplace": "Townsville", | |
"favorite_color": "Red", | |
"unread_messages": 1, | |
"has_pets": true, | |
"shoe_size": 7.0, | |
"coffee_preference": "Black", | |
"dream_destination": "Japan", | |
"music_genre": "Electronic", | |
"is_vegan": true, | |
"fitness_level": "Intermediate", | |
"lucky_number": 10 | |
}, | |
{ | |
"id": 16, | |
"first_name": "Peter", | |
"last_name": "Wright", | |
"email": "[email protected]", | |
"age": 37, | |
"last_login_date": "2023-08-08T12:30:00", | |
"friends_user_ids": [6, 15, 18], | |
"favorite_animal": "Bear", | |
"least_favorite_smell": "Gasoline", | |
"hobbies": ["Reading", "Biking"], | |
"birthplace": "Seaville", | |
"favorite_color": "Blue", | |
"unread_messages": 0, | |
"has_pets": false, | |
"shoe_size": 9.5, | |
"coffee_preference": "Mocha", | |
"dream_destination": "New Zealand", | |
"music_genre": "Indie Rock", | |
"is_vegan": false, | |
"fitness_level": "Advanced", | |
"lucky_number": 7 | |
}, | |
{ | |
"id": 17, | |
"first_name": "Quinn", | |
"last_name": "Hernandez", | |
"email": "[email protected]", | |
"age": 25, | |
"last_login_date": "2023-08-09T09:05:00", | |
"friends_user_ids": [8, 16, 19], | |
"favorite_animal": "Fox", | |
"least_favorite_smell": "Wet Carpet", | |
"hobbies": ["Painting", "Singing"], | |
"birthplace": "Mountainville", | |
"favorite_color": "Orange", | |
"unread_messages": 4, | |
"has_pets": true, | |
"shoe_size": 8.0, | |
"coffee_preference": "Latte", | |
"dream_destination": "Greece", | |
"music_genre": "Pop", | |
"is_vegan": true, | |
"fitness_level": "Beginner", | |
"lucky_number": 22 | |
}, | |
{ | |
"id": 18, | |
"first_name": "Ryan", | |
"last_name": "Adams", | |
"email": "[email protected]", | |
"age": 32, | |
"last_login_date": "2023-08-08T14:25:00", | |
"friends_user_ids": [9, 15, 20], | |
"favorite_animal": "Gorilla", | |
"least_favorite_smell": "Burnt Popcorn", | |
"hobbies": ["Gaming", "Hiking"], | |
"birthplace": "Villageville", | |
"favorite_color": "Green", | |
"unread_messages": 6, | |
"has_pets": true, | |
"shoe_size": 10.5, | |
"coffee_preference": "Black", | |
"dream_destination": "Hawaii", | |
"music_genre": "Electronic", | |
"is_vegan": false, | |
"fitness_level": "Intermediate", | |
"lucky_number": 18 | |
}, | |
{ | |
"id": 19, | |
"first_name": "Sophia", | |
"last_name": "Gonzalez", | |
"email": "[email protected]", | |
"age": 28, | |
"last_login_date": "2023-08-09T13:00:00", | |
"friends_user_ids": [10, 17, 20], | |
"favorite_animal": "Llama", | |
"least_favorite_smell": "Public Restrooms", | |
"hobbies": ["Reading", "Dancing"], | |
"birthplace": "Cityville", | |
"favorite_color": "Purple", | |
"unread_messages": 2, | |
"has_pets": true, | |
"shoe_size": 8.0, | |
"coffee_preference": "Latte", | |
"dream_destination": "Paris", | |
"music_genre": "Pop", | |
"is_vegan": true, | |
"fitness_level": "Advanced", | |
"lucky_number": 4 | |
}, | |
{ | |
"id": 20, | |
"first_name": "Thomas", | |
"last_name": "Walker", | |
"email": "[email protected]", | |
"age": 30, | |
"last_login_date": "2023-08-08T19:45:00", | |
"friends_user_ids": [11, 19], | |
"favorite_animal": "Monkey", | |
"least_favorite_smell": "Sewage", | |
"hobbies": ["Cooking", "Traveling"], | |
"birthplace": "Townsville", | |
"favorite_color": "Blue", | |
"unread_messages": 7, | |
"has_pets": false, | |
"shoe_size": 9.5, | |
"coffee_preference": "Cappuccino", | |
"dream_destination": "Maldives", | |
"music_genre": "Rock", | |
"is_vegan": false, | |
"fitness_level": "Intermediate", | |
"lucky_number": 16 | |
} | |
] |
UserProfile.kt
package com.blakebarrett.myapplication
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.blakebarrett.myapplication.ui.theme.DIALTheme
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Preview(showBackground = true)
@Composable
fun UserProfileScreenPreview() {
DIALTheme {
InitAppWithNavigation()
}
}
@Composable
fun UserProfileApp() {
DIALTheme {
InitAppWithNavigation()
}
}
object Routes {
const val FRIENDS_LIST = "friendsList"
private const val PROFILE = "profile"
fun profile(userId: Int) = "$PROFILE/$userId"
}
@Composable
fun InitAppWithNavigation() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Routes.FRIENDS_LIST
) {
composable(
"profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.IntType })
) { backStackEntry ->
val userId = backStackEntry.arguments?.getInt("userId")
userId?.let {
Scaffold(
bottomBar = {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.background(Color.Magenta),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
Text(
text = "All Users",
modifier = Modifier
.weight(1f)
.clickable {
navController.navigate(Routes.FRIENDS_LIST)
}
.padding(16.dp),
fontStyle = MaterialTheme.typography.bodyMedium.fontStyle
)
Text(
text = "Back",
modifier = Modifier
.weight(1f)
.clickable {
navController.popBackStack()
}
.padding(16.dp),
fontStyle = MaterialTheme.typography.bodyMedium.fontStyle
)
}
}
) { padding ->
UserProfileScreen(
modifier = Modifier.padding(padding),
userId = userId,
navigateToUserId = { friendId ->
navController.navigate(Routes.profile(friendId))
}
)
}
}
}
composable(Routes.FRIENDS_LIST) {
LazyColumn (
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
val allUsers = User.parse(data)
items(allUsers.count()) {index ->
val user = allUsers[index]
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.LightGray, MaterialTheme.shapes.medium)
.clickable {
navController.navigate(Routes.profile(user.id))
}
.padding(16.dp)
) {
Text("${user.first_name} ${user.last_name}")
}
}
}
}
}
}
@Composable
fun UserProfileScreen(modifier: Modifier = Modifier,
userId: Int,
navigateToUserId: (userId: Int) -> Unit = { _ -> }) {
val model = viewModel<UserViewModelLocator>()
model.updateUiStateWithUserViewModel(userId)
model.uiState.collectAsStateWithLifecycle().let { user ->
Column(
modifier = modifier
) {
Text(
text = "User Profile",
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
user.value?.let {
UserDetailCard(it, navigateToUserId)
}
Spacer(modifier = Modifier.height(16.dp))
}
} ?: run {
Text(
text = "User not found",
style = MaterialTheme.typography.headlineMedium
)
}
}
@Composable
fun UserDetailCard(
user: UserViewModelUiState,
friendClick: (Int) -> Unit = { _ -> }
) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(
defaultElevation = 10.dp
)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "${user.first_name} ${user.last_name}",
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Age: ${user.age}",
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Email: ${user.email}",
style = MaterialTheme.typography.bodySmall
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Favorite Animal: ${user.favorite_animal}",
style = MaterialTheme.typography.bodySmall
)
Spacer(modifier = Modifier.height(8.dp))
UserFriendsList(
user.friends_user_ids,
onFriendClicked = friendClick
)
Spacer(modifier = Modifier.height(8.dp))
UserHobbies(user.hobbies)
}
}
}
@Composable
fun UserHobbies(hobbies: List<String>) {
Column {
Text(
text = "Hobbies",
style = MaterialTheme.typography.labelSmall
)
Spacer(modifier = Modifier.height(8.dp))
Column {
hobbies.forEach { hobby ->
Text(
text = "- $hobby",
style = MaterialTheme.typography.bodyMedium
)
}
}
}
}
@Composable
fun UserFriendsList(
friends_user_ids: List<Int>,
onFriendClicked: (Int) -> Unit = {}
) {
Column {
Text(
text = "Friends",
style = MaterialTheme.typography.labelSmall
)
Spacer(modifier = Modifier.height(8.dp))
Column {
friends_user_ids.forEach { friendId ->
viewModel<UserViewModelLocator>()
.getUserById(friendId)?.let { user ->
Text(
text = "- ${user.first_name} ${user.last_name}",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.clickable {
onFriendClicked(friendId)
}
)
}
}
}
}
}
data class UserViewModelUiState(
val first_name: String,
val last_name: String,
val age: Int,
val email: String,
val favorite_animal: String,
val hobbies: List<String>,
val friends_user_ids: List<Int>
)
class UserViewModelLocator : ViewModel() {
private val _allUsers: List<User> = User.parse(data)
private val _uiState = MutableStateFlow<UserViewModelUiState?>(null)
val uiState: StateFlow<UserViewModelUiState?> = _uiState.asStateFlow()
fun getUserById(userId: Int): UserViewModelUiState? {
return _allUsers.find { it.id == userId }?.let { user ->
UserViewModelUiState(
first_name = user.first_name,
last_name = user.last_name,
age = user.age,
email = user.email,
favorite_animal = user.favorite_animal,
hobbies = user.hobbies,
friends_user_ids = user.friends_user_ids
)
}
}
fun updateUiStateWithUserViewModel(userId: Int) {
getUserById(userId)?.let { user ->
_uiState.update {
it?.copy(
first_name = user.first_name,
last_name = user.last_name,
age = user.age,
email = user.email,
favorite_animal = user.favorite_animal,
hobbies = user.hobbies,
friends_user_ids = user.friends_user_ids
) ?: run {
UserViewModelUiState(
first_name = user.first_name,
last_name = user.last_name,
age = user.age,
email = user.email,
favorite_animal = user.favorite_animal,
hobbies = user.hobbies,
friends_user_ids = user.friends_user_ids
)
}
}
}
}
}
@Serializable
data class User(
val id: Int,
val first_name: String,
val last_name: String,
val email: String,
val age: Int,
val last_login_date: String,
val friends_user_ids: List<Int>,
val favorite_animal: String,
val least_favorite_smell: String,
val hobbies: List<String>,
val birthplace: String,
val favorite_color: String,
val unread_messages: Int,
val has_pets: Boolean,
val shoe_size: Double,
val coffee_preference: String,
val dream_destination: String,
val music_genre: String,
val is_vegan: Boolean,
val fitness_level: String,
val lucky_number: Int
) {
companion object {
fun parse(source: String): List<User> {
return Json.decodeFromString(source)
}
}
}
const val data = """
[
{
"id": 1,
"first_name": "Alice",
"last_name": "Smith",
"email": "[email protected]",
"age": 28,
"last_login_date": "2023-08-09T10:30:00",
"friends_user_ids": [2, 3, 5, 7],
"favorite_animal": "Dog",
"least_favorite_smell": "Durian",
"hobbies": ["Painting", "Hiking"],
"birthplace": "Cityville",
"favorite_color": "Purple",
"unread_messages": 3,
"has_pets": true,
"shoe_size": 7.5,
"coffee_preference": "Black",
"dream_destination": "Bora Bora",
"music_genre": "Indie Rock",
"is_vegan": false,
"fitness_level": "Intermediate",
"lucky_number": 17
},
{
"id": 2,
"first_name": "Bob",
"last_name": "Johnson",
"email": "[email protected]",
"age": 35,
"last_login_date": "2023-08-08T15:20:00",
"friends_user_ids": [1, 4, 8],
"favorite_animal": "Cat",
"least_favorite_smell": "Sulfur",
"hobbies": ["Reading", "Gardening"],
"birthplace": "Villageville",
"favorite_color": "Blue",
"unread_messages": 0,
"has_pets": true,
"shoe_size": 9.0,
"coffee_preference": "Latte",
"dream_destination": "Paris",
"music_genre": "Classical",
"is_vegan": true,
"fitness_level": "Beginner",
"lucky_number": 5
},
{
"id": 3,
"first_name": "Charlie",
"last_name": "Brown",
"email": "[email protected]",
"age": 22,
"last_login_date": "2023-08-09T08:45:00",
"friends_user_ids": [1, 5, 9],
"favorite_animal": "Elephant",
"least_favorite_smell": "Fish",
"hobbies": ["Cooking", "Playing Guitar"],
"birthplace": "Townsville",
"favorite_color": "Green",
"unread_messages": 10,
"has_pets": false,
"shoe_size": 8.5,
"coffee_preference": "Cappuccino",
"dream_destination": "Tokyo",
"music_genre": "Pop",
"is_vegan": false,
"fitness_level": "Advanced",
"lucky_number": 12
},
{
"id": 4,
"first_name": "David",
"last_name": "Lee",
"email": "[email protected]",
"age": 31,
"last_login_date": "2023-08-07T18:10:00",
"friends_user_ids": [2, 8, 10],
"favorite_animal": "Lion",
"least_favorite_smell": "Garlic",
"hobbies": ["Soccer", "Photography"],
"birthplace": "Countryville",
"favorite_color": "Yellow",
"unread_messages": 5,
"has_pets": true,
"shoe_size": 10.5,
"coffee_preference": "Espresso",
"dream_destination": "New York",
"music_genre": "Rock",
"is_vegan": false,
"fitness_level": "Intermediate",
"lucky_number": 9
},
{
"id": 5,
"first_name": "Eve",
"last_name": "Williams",
"email": "[email protected]",
"age": 27,
"last_login_date": "2023-08-09T12:05:00",
"friends_user_ids": [1, 3, 9, 11],
"favorite_animal": "Dolphin",
"least_favorite_smell": "Onion",
"hobbies": ["Yoga", "Traveling"],
"birthplace": "Seaville",
"favorite_color": "Turquoise",
"unread_messages": 8,
"has_pets": true,
"shoe_size": 8.0,
"coffee_preference": "Mocha",
"dream_destination": "Maldives",
"music_genre": "Electronic",
"is_vegan": true,
"fitness_level": "Advanced",
"lucky_number": 3
},
{
"id": 6,
"first_name": "Frank",
"last_name": "Davis",
"email": "[email protected]",
"age": 45,
"last_login_date": "2023-08-08T09:40:00",
"friends_user_ids": [12, 13, 14],
"favorite_animal": "Giraffe",
"least_favorite_smell": "Vinegar",
"hobbies": ["Golf", "Painting"],
"birthplace": "Mountainville",
"favorite_color": "Orange",
"unread_messages": 2,
"has_pets": false,
"shoe_size": 11.0,
"coffee_preference": "Americano",
"dream_destination": "Switzerland",
"music_genre": "Jazz",
"is_vegan": false,
"fitness_level": "Beginner",
"lucky_number": 8
},
{
"id": 7,
"first_name": "Grace",
"last_name": "Martinez",
"email": "[email protected]",
"age": 29,
"last_login_date": "2023-08-09T16:15:00",
"friends_user_ids": [1, 15, 16],
"favorite_animal": "Penguin",
"least_favorite_smell": "Cabbage",
"hobbies": ["Singing", "Cooking"],
"birthplace": "Snowville",
"favorite_color": "White",
"unread_messages": 1,
"has_pets": true,
"shoe_size": 6.5,
"coffee_preference": "Latte",
"dream_destination": "Hawaii",
"music_genre": "Reggae",
"is_vegan": true,
"fitness_level": "Intermediate",
"lucky_number": 13
},
{
"id": 8,
"first_name": "Henry",
"last_name": "Taylor",
"email": "[email protected]",
"age": 32,
"last_login_date": "2023-08-08T13:30:00",
"friends_user_ids": [2, 4, 9, 17],
"favorite_animal": "Tiger",
"least_favorite_smell": "Mold",
"hobbies": ["Running", "Chess"],
"birthplace": "Desertville",
"favorite_color": "Red",
"unread_messages": 12,
"has_pets": true,
"shoe_size": 10.0,
"coffee_preference": "Cappuccino",
"dream_destination": "Australia",
"music_genre": "Country",
"is_vegan": false,
"fitness_level": "Advanced",
"lucky_number": 21
},
{
"id": 9,
"first_name": "Ivy",
"last_name": "Anderson",
"email": "[email protected]",
"age": 24,
"last_login_date": "2023-08-09T07:55:00",
"friends_user_ids": [3, 5, 8, 18],
"favorite_animal": "Kangaroo",
"least_favorite_smell": "Smoked Fish",
"hobbies": ["Dancing", "Biking"],
"birthplace": "Jungleville",
"favorite_color": "Yellow",
"unread_messages": 6,
"has_pets": true,
"shoe_size": 8.0,
"coffee_preference": "Espresso",
"dream_destination": "Brazil",
"music_genre": "Hip Hop",
"is_vegan": true,
"fitness_level": "Beginner",
"lucky_number": 6
},
{
"id": 10,
"first_name": "Jack",
"last_name": "Moore",
"email": "[email protected]",
"age": 30,
"last_login_date": "2023-08-07T21:20:00",
"friends_user_ids": [4, 7, 9, 19],
"favorite_animal": "Horse",
"least_favorite_smell": "Burnt Rubber",
"hobbies": ["Photography", "Travelling"],
"birthplace": "Farmville",
"favorite_color": "Brown",
"unread_messages": 9,
"has_pets": true,
"shoe_size": 10.5,
"coffee_preference": "Black",
"dream_destination": "New Zealand",
"music_genre": "Alternative",
"is_vegan": false,
"fitness_level": "Intermediate",
"lucky_number": 11
},
{
"id": 11,
"first_name": "Karen",
"last_name": "Jackson",
"email": "[email protected]",
"age": 26,
"last_login_date": "2023-08-09T14:50:00",
"friends_user_ids": [5, 10, 20],
"favorite_animal": "Panda",
"least_favorite_smell": "Rotting Fruit",
"hobbies": ["Yoga", "Reading"],
"birthplace": "Cityville",
"favorite_color": "Pink",
"unread_messages": 4,
"has_pets": false,
"shoe_size": 7.0,
"coffee_preference": "Mocha",
"dream_destination": "Thailand",
"music_genre": "R&B",
"is_vegan": true,
"fitness_level": "Advanced",
"lucky_number": 15
},
{
"id": 12,
"first_name": "Liam",
"last_name": "Garcia",
"email": "[email protected]",
"age": 21,
"last_login_date": "2023-08-08T08:00:00",
"friends_user_ids": [6, 13, 15],
"favorite_animal": "Sloth",
"least_favorite_smell": "Dirty Socks",
"hobbies": ["Gaming", "Cooking"],
"birthplace": "Villageville",
"favorite_color": "Black",
"unread_messages": 7,
"has_pets": true,
"shoe_size": 9.5,
"coffee_preference": "Latte",
"dream_destination": "Greece",
"music_genre": "Metal",
"is_vegan": false,
"fitness_level": "Beginner",
"lucky_number": 14
},
{
"id": 13,
"first_name": "Mia",
"last_name": "Rodriguez",
"email": "[email protected]",
"age": 33,
"last_login_date": "2023-08-09T11:40:00",
"friends_user_ids": [6, 12, 14, 16],
"favorite_animal": "Owl",
"least_favorite_smell": "Stale Beer",
"hobbies": ["Singing", "Painting"],
"birthplace": "Countryville",
"favorite_color": "Blue",
"unread_messages": 5,
"has_pets": true,
"shoe_size": 8.5,
"coffee_preference": "Cappuccino",
"dream_destination": "Italy",
"music_genre": "Pop",
"is_vegan": true,
"fitness_level": "Intermediate",
"lucky_number": 8
},
{
"id": 14,
"first_name": "Noah",
"last_name": "Martinez",
"email": "[email protected]",
"age": 40,
"last_login_date": "2023-08-08T17:55:00",
"friends_user_ids": [6, 13, 15],
"favorite_animal": "Wolf",
"least_favorite_smell": "Mothballs",
"hobbies": ["Running", "Cooking"],
"birthplace": "Cityville",
"favorite_color": "Green",
"unread_messages": 2,
"has_pets": false,
"shoe_size": 10.0,
"coffee_preference": "Espresso",
"dream_destination": "Australia",
"music_genre": "Rock",
"is_vegan": false,
"fitness_level": "Advanced",
"lucky_number": 19
},
{
"id": 15,
"first_name": "Olivia",
"last_name": "Thompson",
"email": "[email protected]",
"age": 29,
"last_login_date": "2023-08-09T10:15:00",
"friends_user_ids": [7, 13, 14, 17],
"favorite_animal": "Duck",
"least_favorite_smell": "Wet Dog",
"hobbies": ["Soccer", "Gardening"],
"birthplace": "Townsville",
"favorite_color": "Red",
"unread_messages": 1,
"has_pets": true,
"shoe_size": 7.0,
"coffee_preference": "Black",
"dream_destination": "Japan",
"music_genre": "Electronic",
"is_vegan": true,
"fitness_level": "Intermediate",
"lucky_number": 10
},
{
"id": 16,
"first_name": "Peter",
"last_name": "Wright",
"email": "[email protected]",
"age": 37,
"last_login_date": "2023-08-08T12:30:00",
"friends_user_ids": [6, 15, 18],
"favorite_animal": "Bear",
"least_favorite_smell": "Gasoline",
"hobbies": ["Reading", "Biking"],
"birthplace": "Seaville",
"favorite_color": "Blue",
"unread_messages": 0,
"has_pets": false,
"shoe_size": 9.5,
"coffee_preference": "Mocha",
"dream_destination": "New Zealand",
"music_genre": "Indie Rock",
"is_vegan": false,
"fitness_level": "Advanced",
"lucky_number": 7
},
{
"id": 17,
"first_name": "Quinn",
"last_name": "Hernandez",
"email": "[email protected]",
"age": 25,
"last_login_date": "2023-08-09T09:05:00",
"friends_user_ids": [8, 16, 19],
"favorite_animal": "Fox",
"least_favorite_smell": "Wet Carpet",
"hobbies": ["Painting", "Singing"],
"birthplace": "Mountainville",
"favorite_color": "Orange",
"unread_messages": 4,
"has_pets": true,
"shoe_size": 8.0,
"coffee_preference": "Latte",
"dream_destination": "Greece",
"music_genre": "Pop",
"is_vegan": true,
"fitness_level": "Beginner",
"lucky_number": 22
},
{
"id": 18,
"first_name": "Ryan",
"last_name": "Adams",
"email": "[email protected]",
"age": 32,
"last_login_date": "2023-08-08T14:25:00",
"friends_user_ids": [9, 15, 20],
"favorite_animal": "Gorilla",
"least_favorite_smell": "Burnt Popcorn",
"hobbies": ["Gaming", "Hiking"],
"birthplace": "Villageville",
"favorite_color": "Green",
"unread_messages": 6,
"has_pets": true,
"shoe_size": 10.5,
"coffee_preference": "Black",
"dream_destination": "Hawaii",
"music_genre": "Electronic",
"is_vegan": false,
"fitness_level": "Intermediate",
"lucky_number": 18
},
{
"id": 19,
"first_name": "Sophia",
"last_name": "Gonzalez",
"email": "[email protected]",
"age": 28,
"last_login_date": "2023-08-09T13:00:00",
"friends_user_ids": [10, 17, 20],
"favorite_animal": "Llama",
"least_favorite_smell": "Public Restrooms",
"hobbies": ["Reading", "Dancing"],
"birthplace": "Cityville",
"favorite_color": "Purple",
"unread_messages": 2,
"has_pets": true,
"shoe_size": 8.0,
"coffee_preference": "Latte",
"dream_destination": "Paris",
"music_genre": "Pop",
"is_vegan": true,
"fitness_level": "Advanced",
"lucky_number": 4
},
{
"id": 20,
"first_name": "Thomas",
"last_name": "Walker",
"email": "[email protected]",
"age": 30,
"last_login_date": "2023-08-08T19:45:00",
"friends_user_ids": [11, 19],
"favorite_animal": "Monkey",
"least_favorite_smell": "Sewage",
"hobbies": ["Cooking", "Traveling"],
"birthplace": "Townsville",
"favorite_color": "Blue",
"unread_messages": 7,
"has_pets": false,
"shoe_size": 9.5,
"coffee_preference": "Cappuccino",
"dream_destination": "Maldives",
"music_genre": "Rock",
"is_vegan": false,
"fitness_level": "Intermediate",
"lucky_number": 16
}
]
"""
MyComposableUnitTest.kt
import androidx.compose.material3.Text
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import org.junit.Rule
import org.junit.Test
class MyComposableTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun testMyComposable() {
composeTestRule.setContent {
// Call your Composable function here
Text("Hello, World!")
}
// Use onNodeWithText or other assertions if needed
composeTestRule.onNodeWithText("Hello, World!").assertExists()
}
}
build.gradle
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.8.10"
}
android {
namespace = "com.blakebarrett.myapplication"
compileSdk = 34
defaultConfig {
applicationId = "com.blakebarrett.myapplication"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
val lifecycle_version = "2.6.1"
val compose_version = "1.5.0"
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3:1.1.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest:1.5.0")
// Kotlin serialization
implementation("org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
// ViewModel utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
// Lifecycle utilities for Compose
implementation("androidx.lifecycle:lifecycle-runtime-compose:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
implementation("androidx.compose.runtime:runtime:$compose_version")
implementation("androidx.compose.runtime:runtime-livedata:$compose_version")
// Test rules and transitive dependencies:
testImplementation("androidx.compose.ui:ui-test-junit4:$compose_version")
// Needed for createAndroidComposeRule, but not createComposeRule:
testImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
// Test rules and transitive dependencies:
androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_version")
// Needed for createAndroidComposeRule, but not createComposeRule:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.1")
// or Material Design 2
implementation("androidx.compose.material:material")
// or skip Material Design and build directly on top of foundational components
implementation("androidx.compose.foundation:foundation")
val nav_version = "2.7.1"
implementation("androidx.navigation:navigation-compose:$nav_version")
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MainAcitivy.kt