Skip to main content

Overview

The Home Screen serves as the main navigation hub for NASA Explorer. It implements a scaffold layout with a custom top app bar, bottom navigation bar, and hosts multiple nested screens including Daily Image, Random Images, Range Images, and Favorites.

Key Features

Bottom Navigation

Five navigation items for quick access to all major features

Top App Bar

Custom header with branding and logout functionality

Nested Navigation

NavHost integration for smooth transitions between sections

Animated Transitions

Fade animations for screen transitions (1500ms duration)

Architecture

Main HomeScreen Composable

@Composable
fun HomeScreen(
    homeScreenViewModel: HomeScreenViewModel = hiltViewModel(),
    onNavigateToLogin: () -> Unit
) {
    val navController = rememberNavController()

    BackHandler {
        navController.popBackStack(Routes.Home, inclusive = false)
    }

    Scaffold(
        topBar = {
            HomeTopBar(
                navController = navController,
                homeScreenViewModel = homeScreenViewModel,
                onNavigateToLogin = onNavigateToLogin
            )
        },
        bottomBar = {
            HomeBottomBar(navController = navController)
        }
    ) { paddingValues ->
        // NavHost implementation
    }
}

Screen Components

Home Content

The default home content displays a grid of NASA images:
@Composable
fun HomeScreenContent() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.fondo),
            contentDescription = "Background",
            modifier = Modifier.fillMaxSize(),
            contentScale = ContentScale.Crop
        )
        
        Column(
            Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            // Two rows with two images each
        }
    }
}
The home content displays 4 sample NASA images in a 2x2 grid layout with rounded corners and borders.

Top App Bar

HomeTopBar Implementation

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeTopBar(
    navController: NavController,
    homeScreenViewModel: HomeScreenViewModel,
    onNavigateToLogin: () -> Unit
) {
    TopAppBar(
        title = { 
            Text(
                text = "NASA EXPLORER", 
                style = MaterialTheme.typography.titleLarge
            ) 
        },
        colors = TopAppBarDefaults.topAppBarColors(
            containerColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.8f),
            titleContentColor = MaterialTheme.colorScheme.onPrimary,
            navigationIconContentColor = MaterialTheme.colorScheme.onPrimary
        ),
        modifier = Modifier.shadow(4.dp),
        navigationIcon = {
            IconButton(onClick = { navController.navigate(Routes.Home) }) {
                Icon(
                    painter = painterResource(id = R.drawable.planet_solid),
                    contentDescription = "Button Home",
                    tint = MaterialTheme.colorScheme.onPrimary
                )
            }
        },
        actions = {
            Text(
                text = stringResource(R.string.close_session),
                color = MaterialTheme.colorScheme.onPrimary,
                style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier
                    .padding(end = 18.dp)
                    .clickable {
                        homeScreenViewModel.logOut()
                        onNavigateToLogin()
                    }
            )
        }
    )
}

Top Bar Features

“NASA EXPLORER” displayed in the title using MaterialTheme.typography.titleLarge
Planet icon that navigates back to home screen when clicked
Clickable text that triggers logout and navigation to login screen:
homeScreenViewModel.logOut()
onNavigateToLogin()
  • Semi-transparent primary color background (80% alpha)
  • 4dp shadow elevation
  • OnPrimary color for text and icons

Bottom Navigation Bar

HomeBottomBar Implementation

@Composable
fun HomeBottomBar(navController: NavController) {
    var selectedItem by remember { mutableIntStateOf(-1) }

    NavigationBar(
        containerColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.8f)
    ) {
        // Navigation items
    }
}
Icon: Icons.Default.HomeLabel: “Inicio”Route: Routes.Home
NavigationBarItem(
    selected = selectedItem == 0,
    onClick = {
        if (selectedItem != 0) {
            selectedItem = 0
            navController.navigate(Routes.Home) {
                popUpTo<Routes.Home> { inclusive = false }
            }
        }
    },
    icon = { Icon(imageVector = Icons.Default.Home, contentDescription = "Home") },
    label = { Text(text = "Inicio") }
)
colors = NavigationBarItemDefaults.colors(
    indicatorColor = MaterialTheme.colorScheme.secondary,
    selectedIconColor = MaterialTheme.colorScheme.onSecondary,
    selectedTextColor = MaterialTheme.colorScheme.onSecondary,
    unselectedIconColor = MaterialTheme.colorScheme.onPrimary,
    unselectedTextColor = MaterialTheme.colorScheme.onPrimary
)
NavHost(
    navController = navController,
    startDestination = Routes.Home,
    enterTransition = { fadeIn(animationSpec = tween(1500)) },
    exitTransition = { fadeOut(animationSpec = tween(1500)) },
    modifier = Modifier
        .fillMaxSize()
        .background(Color.Black)
        .padding(paddingValues)
) {
    composable<Routes.Home> { HomeScreenContent() }
    composable<Routes.DailyImage> { DailyImageScreen() }
    composable<Routes.RandomImage> { RandomImageScreen() }
    composable<Routes.RangeImages> { RangeImagesScreen() }
    composable<Routes.FavoriteImages> { FavoritesScreen() }
}
Animation Duration: All transitions use 1500ms fade animations for smooth visual effects.

ViewModel

HomeScreenViewModel

Manages logout functionality:
@HiltViewModel
class HomeScreenViewModel @Inject constructor(
    private val authService: AuthService
) : ViewModel() {

    fun logOut() {
        viewModelScope.launch(Dispatchers.IO) {
            authService.userLogout()
        }
    }
}
Logout operations run on Dispatchers.IO to handle potential network calls asynchronously.

Back Handler

Custom back button behavior ensures users return to home screen:
BackHandler {
    navController.popBackStack(Routes.Home, inclusive = false)
}

Image Grid Layout

The home content displays images in a structured grid:
// First row
Row(
    Modifier
        .fillMaxWidth()
        .padding(bottom = 24.dp),
    horizontalArrangement = Arrangement.SpaceEvenly,
    verticalAlignment = Alignment.CenterVertically
) {
    Image(
        painter = painterResource(id = R.drawable.imagen1),
        contentDescription = "Image 1",
        modifier = Modifier
            .size(160.dp)
            .clip(RoundedCornerShape(16.dp))
            .border(
                BorderStroke(1.dp, MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)),
                shape = RoundedCornerShape(16.dp)
            ),
        contentScale = ContentScale.Crop
    )
    // Second image
}

Image Styling

  • Size: 160x160dp
  • Shape: Rounded corners (16dp radius)
  • Border: 1dp with 60% opacity
  • Content Scale: Crop

Routes

The screen uses type-safe navigation routes:
import com.ccandeladev.nasaexplorer.ui.core.Routes

// Available routes:
Routes.Home
Routes.DailyImage
Routes.RandomImage
Routes.RangeImages
Routes.FavoriteImages

Dependencies

import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

Material 3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.TopAppBar

Animation

import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut

File Location

app/src/main/java/com/ccandeladev/nasaexplorer/ui/homescreen/
├── HomeScreen.kt
└── HomeScreenViewModel.kt
Best Practice: The screen uses Scaffold for structured layout and NavHost for nested navigation, following Material Design 3 guidelines.

Build docs developers (and LLMs) love