Wednesday, October 13, 2021

jetpack compose - Navigation object argument

MainActivity.kt

package com.cfsuman.jetpackcompose

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
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.google.gson.Gson


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedObjectState: Bundle?) {
        super.onCreate(savedObjectState)
        setContent {
            GetScaffold()
        }
    }


    @Composable
    fun GetScaffold(){
        val navController:NavHostController = rememberNavController()

        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text(
                        text = "Compose - Nav Object Argument"
                    )},
                    backgroundColor = Color(0xFFC0E8D5),
                )
            },
            content = {MainContent(navController)},
            backgroundColor = Color(0xFFEDEAE0),
        )
    }


    @Composable
    fun MainContent(navController: NavHostController){
        Box(
            modifier = Modifier.fillMaxSize(),
        ){
            MainNavigation(navController)
        }
    }


    @Composable
    fun MainNavigation(navController: NavHostController){
        NavHost(
            navController = navController,
            startDestination = "listScreen"
        ){
            composable("listScreen"){ListScreen(navController)}

            composable(
                route = "detailsScreen/{colorObject}",
                arguments = listOf(
                    navArgument("colorObject")
                        { type = NavType.StringType },
                )
            ){ backStackEntry ->
                backStackEntry.arguments
                    ?.getString("colorObject").let { json->
                    val colorObject = Gson().fromJson(
                        json,ColorObject::class.java
                    )
                    DetailsScreen(colorObject = colorObject)

                }
            }
        }
    }


    @Composable
    fun ListScreen(navController: NavController){
        fun navigateToColorObject(colorObject: ColorObject){
            val colorJson = Gson().toJson(colorObject)
            navController.navigate("detailsScreen/$colorJson")
        }

        val colors = listOf<ColorObject>(
            ColorObject("Brick red",0xFFCB4154),
            ColorObject("Baby blue",0xFF89CFF0),
            ColorObject("Brilliant rose",0xFFFF55A3),
            ColorObject("Cadmium orange",0xFFED872D),
            ColorObject("Cameo pink",0xFFEFBBCC)
        )
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(4.dp),
            verticalArrangement = Arrangement.spacedBy(4.dp),
            horizontalAlignment = Alignment.Start
        ) {
            Text(
                text = "List Screen",
                style = MaterialTheme.typography.h4,
                modifier = Modifier.padding(bottom = 24.dp)
            )

            colors.forEach {
                Card(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(1.dp)
                        .height(75.dp)
                        .clickable {
                            navigateToColorObject(it)
                        }
                ) {
                    Box(modifier = Modifier
                        .fillMaxSize()
                        .wrapContentSize(Alignment.Center)) {
                        Text(
                            text = it.name,
                            fontWeight = FontWeight.Bold
                        )
                    }
                }
            }
        }
    }


    @Composable
    fun DetailsScreen(colorObject:ColorObject?){
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color(colorObject?.value ?: 0xFFFFFF)),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = colorObject?.name?:"",
                style = MaterialTheme.typography.h4,
                modifier = Modifier.padding(bottom = 24.dp),
                textAlign = TextAlign.Center
            )
        }
    }
}


data class ColorObject(
    val name:String,
    val value:Long
)
build.gradle [dependencies]

implementation 'androidx.navigation:navigation-compose:2.4.0-alpha10'
implementation 'com.google.code.gson:gson:2.8.6'