17 - Componentes TabRow y Tab (fila de pestañas)

Las pestañas nos permiten organizar contenido en diferentes pantallas. Una pestaña representa una sola página de contenido mediante una etiqueta de texto y/o un icono.

La función composable Tab se debe usar dentro de la función TabRow (fila de pestañas)

Problema

Confeccionar una aplicación con tres pestañas que muestren datos generales de 3 paises.

Crear un proyecto llamado Compose19, la interfaz visual de la misma debe ser similar a:

TabRow y Tab Jetpack Compose

Agregamos la dependencia de Navigation Compose en el archivo Gradle:

dependencies {

    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
    implementation("androidx.navigation:navigation-compose:2.4.0-alpha06") 
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
}

El código fuente que debemos implementar es:

package com.tutorialesprogramacionya.compose19

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PantallaPrincipal()
        }
    }
}

@Composable
fun PantallaPrincipal() {

    val navController = rememberNavController()
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "Países Latinoamericanos")
                },
                navigationIcon = {
                    IconButton(onClick = {
                    }) {
                        Icon(Icons.Filled.Menu, contentDescription = null)
                    }
                }
            )
        },
    ) {
        var estado by remember { mutableStateOf(0) }
        val pestañas = listOf("Argentina", "Brasil", "Colombia")
        Column {
            TabRow(selectedTabIndex = estado) {
                pestañas.forEachIndexed { indice, titulo ->
                    Tab(
                        text = { Text(titulo) },
                        selected = estado == indice,
                        onClick = {
                            estado = indice
                            when (estado) {
                                0 -> navController.navigate("pantallaargentina")
                                1 -> navController.navigate("pantallabrasil")
                                2 -> navController.navigate("pantallacolombia")
                            }
                        }
                    )
                }
            }
            NavHost(navController = navController, startDestination = "pantallaargentina") {
                composable("pantallaargentina") {
                    PantallaArgentina()
                }
                composable("pantallabrasil") {
                    PantallaBrasil()
                }
                composable("pantallacolombia") {
                    PantallaColombia()
                }
            }
        }

    }
}

@Composable
fun PantallaArgentina() {
    val scroll = rememberScrollState(0)
    Text(
        text = "Argentina, oficialmente República Argentina",
        modifier = Modifier.verticalScroll(scroll)
    )
}

@Composable
fun PantallaBrasil() {
    val scroll = rememberScrollState(0)
    Text(
        text = "Brasil, oficialmente República Federativa de Brasil",
        modifier = Modifier.verticalScroll(scroll)
    )
}

@Composable
fun PantallaColombia() {
    val scroll = rememberScrollState(0)
    Text(
        text = "Colombia, oficialmente República de Colombia",
        modifier = Modifier.verticalScroll(scroll)
    )
}

Previo a llamar a la función NavHost (que nos permite navegar entre pantalla), procedemos a llamar a la función composable 'TabRox', iniciando el parámetro selectedTabIndex con el número de pestaña activa, utilizamos una variable de estado para permitir su cambio posteriormente.

La función lambda recorre la lista con las etiquetas a mostrar en cada pestaña, aquí es donde llamamos a nuestra segundo función composable llamada 'Tab', que tiene el objetivo de crear cada pestaña, su texto (eventualmente disponer un ícono) y mediante el parámetro onClick configuramos otra función lambda que verifica que número de pestaña se encuentra seleccionada y procede a activar la pantalla respectiva con el controlador de navegación que ya conocemos de conceptos anteriores:

        var estado by remember { mutableStateOf(0) }
        val pestañas = listOf("Argentina", "Brasil", "Colombia")
        Column {
            TabRow(selectedTabIndex = estado) {
                pestañas.forEachIndexed { indice, titulo ->
                    Tab(
                        text = { Text(titulo) },
                        selected = estado == indice,
                        onClick = {
                            estado = indice
                            when (estado) {
                                0 -> navController.navigate("pantallaargentina")
                                1 -> navController.navigate("pantallabrasil")
                                2 -> navController.navigate("pantallacolombia")
                            }
                        }
                    )
                }
            }
            NavHost(navController = navController, startDestination = "pantallaargentina") {
                composable("pantallaargentina") {
                    PantallaArgentina()
                }
                composable("pantallabrasil") {
                    PantallaBrasil()
                }
                composable("pantallacolombia") {
                    PantallaColombia()
                }
            }
        }

Este proyecto lo puede descargar en un zip desde este enlace: Compose19.zip