Skip to content

Commit

Permalink
Updated sample module
Browse files Browse the repository at this point in the history
  • Loading branch information
chRyNaN committed May 22, 2023
1 parent e0fe2a3 commit a1149d2
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import kotlinx.serialization.encoding.Encoder
/**
* A [Navigator] is responsible for coordinating the navigation between the different UI component groupings in an
* application. It is a stateful component that reacts to [NavigationEvent]s that are emitted via calls to the
* navigation functions ([goTo], [handleBack], and [changeContext]) and updates its stored state values which can be
* navigation functions ([goTo], [goBack], and [changeContext]) and updates its stored state values which can be
* accessed via its state [store]. It is up to the user of a [Navigator] to subscribe to the state changes of this
* component and update the associated UI accordingly.
*
Expand All @@ -35,7 +35,7 @@ import kotlinx.serialization.encoding.Encoder
*
* @see [Navigator] The [Navigator] constructor function for creating an instance of this interface.
* @see [goTo] For navigating to a new [NavigationDestination] within the current [NavigationContext].
* @see [handleBack] For navigating backwards, either within the current [NavigationContext] or across
* @see [goBack] For navigating backwards, either within the current [NavigationContext] or across
* [NavigationContext]s, depending on the [NavigationStrategy.BackwardsNavigation] strategy supplied to the [Navigator]
* function when creating an instance of this [Navigator].
* @see [changeContext] For navigating to a different [NavigationContext].
Expand All @@ -53,7 +53,7 @@ sealed interface Navigator<Destination : NavigationDestination, Context : Naviga
/**
* Dispatches the provided navigation [event] which mutates the underlying state values if the navigation event can
* be performed. The creation of [NavigationEvent]s is handled internally within this library's components,
* therefore, instead of invoking this function explicitly, use the [handleBack], [goTo], and [changeContext]
* therefore, instead of invoking this function explicitly, use the [goBack], [goTo], and [changeContext]
* functions.
*
* @param [event] The [NavigationEvent] that represents the navigation action to be performed.
Expand Down Expand Up @@ -87,7 +87,7 @@ sealed interface Navigator<Destination : NavigationDestination, Context : Naviga
* @return `true` if the back navigation operation was successful, `false` otherwise.
*/
@ExperimentalNavigationApi
fun <Destination : NavigationDestination, Context : NavigationContext<Destination>> Navigator<Destination, Context>.handleBack(): Boolean =
fun <Destination : NavigationDestination, Context : NavigationContext<Destination>> Navigator<Destination, Context>.goBack(): Boolean =
dispatch(event = NavigationEvent.Backward())

/**
Expand Down Expand Up @@ -246,7 +246,7 @@ internal class NavigatorImpl<Destination : NavigationDestination, Context : Navi

internal constructor(
initialContext: Context,
duplicateDestinationStrategy: NavigationStrategy.DuplicateDestination = NavigationStrategy.DuplicateDestination.ALLOW_DUPLICATES, // TODO
duplicateDestinationStrategy: NavigationStrategy.DuplicateDestination = NavigationStrategy.DuplicateDestination.ALLOW_DUPLICATES,
backwardsNavigationStrategy: NavigationStrategy.BackwardsNavigation = NavigationStrategy.BackwardsNavigation.IN_CONTEXT,
destinationRetentionStrategy: NavigationStrategy.DestinationRetention = NavigationStrategy.DestinationRetention.RETAIN
) {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material.*
import com.chrynan.navigation.ExperimentalNavigationApi
import com.chrynan.navigation.sample.compose.example.SingleContextSample

@OptIn(ExperimentalNavigationApi::class)
class MainActivity : AppCompatActivity() {

@OptIn(ExperimentalNavigationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
MaterialTheme {
App()
// TODO: Change to desired example: ex: MultipleContextSample
SingleContextSample()
}
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.chrynan.navigation.sample.compose

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.ui.graphics.vector.ImageVector
import com.chrynan.navigation.NavigationContext

sealed class AppDestination {

object Home : AppDestination()

object Search : AppDestination()

object Settings : AppDestination()

data class Details(val itemId: Int) : AppDestination()
}

enum class AppContext(
val title: String,
val icon: ImageVector,
override val initialDestination: AppDestination
) : NavigationContext<AppDestination> {

HOME(title = "Home", icon = Icons.Default.Home, initialDestination = AppDestination.Home),

SEARCH(title = "Search", icon = Icons.Default.Search, initialDestination = AppDestination.Search),

SETTINGS(title = "Settings", icon = Icons.Default.Settings, initialDestination = AppDestination.Settings)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@file:Suppress("FunctionName")

package com.chrynan.navigation.sample.compose.composable

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.ListItem
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp

fun Items(
modifier: Modifier = Modifier,
onItemClick: (itemId: Int) -> Unit,
header: (@Composable () -> Unit)? = null
) {
LazyColumn(modifier = modifier) {
if (header != null) {
item(key = "Header") {
header.invoke()
}
}

items(
count = 10,
key = { it }
) { index ->
Item(
modifier = Modifier.fillMaxWidth(),
title = "Item ${index + 1}",
onClick = {
onItemClick.invoke(index)
}
)
}
}
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun Item(
modifier: Modifier = Modifier,
title: String,
description: String? = null,
icon: ImageVector? = null,
onClick: () -> Unit
) {
ListItem(
modifier = modifier.clickable { onClick.invoke() },
text = {
Text(text = title)
},
secondaryText = {
if (description != null) {
Text(text = description)
}
},
icon = {
if (icon != null) {
Icon(
modifier = Modifier.size(24.dp),
imageVector = icon,
contentDescription = null
)
}
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.chrynan.navigation.sample.compose.example

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.chrynan.navigation.ExperimentalNavigationApi
import com.chrynan.navigation.changeContext
import com.chrynan.navigation.compose.NavigationContainer
import com.chrynan.navigation.compose.rememberNavigator
import com.chrynan.navigation.goTo
import com.chrynan.navigation.sample.compose.AppContext
import com.chrynan.navigation.sample.compose.AppDestination
import com.chrynan.navigation.sample.compose.composable.Items

@ExperimentalNavigationApi
@Composable
fun MultipleContextSample() {
val navigator = rememberNavigator(initialContext = AppContext.HOME)

Column {
Box(modifier = Modifier.weight(1f)) {
NavigationContainer(navigator = navigator) { context, destination ->
when (destination) {
is AppDestination.Home -> Items(
modifier = Modifier.matchParentSize(),
onItemClick = {
navigator.goTo(destination = AppDestination.Details(itemId = it))
},
header = {
Text(text = context.title, style = MaterialTheme.typography.h6)
})

is AppDestination.Details -> Text("${context.title}: ${destination.itemId}")
is AppDestination.Settings -> Text(context.title)
is AppDestination.Search -> Text(context.title)
}
}
}

BottomNavigation {
AppContext.values().forEach { context ->
BottomNavigationItem(
selected = false,
onClick = { navigator.changeContext(context) },
label = { Text(context.title) },
icon = { Image(imageVector = context.icon, contentDescription = null) }
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.chrynan.navigation.sample.compose.example

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.chrynan.navigation.ExperimentalNavigationApi
import com.chrynan.navigation.compose.NavigationContainer
import com.chrynan.navigation.compose.rememberNavigator
import com.chrynan.navigation.goBack
import com.chrynan.navigation.goTo
import com.chrynan.navigation.sample.compose.AppDestination
import com.chrynan.navigation.sample.compose.composable.Items

@Composable
@ExperimentalNavigationApi
fun SingleContextSample() {
val navigator = rememberNavigator<AppDestination>(initialDestination = AppDestination.Home)

BackHandler {
navigator.goBack()
}

NavigationContainer(
navigator = navigator,
modifier = Modifier.fillMaxSize()
) { destination ->
when (destination) {
is AppDestination.Home -> Items(
modifier = Modifier.matchParentSize(),
onItemClick = {
navigator.goTo(destination = AppDestination.Details(itemId = it))
},
header = {
Text(text = "Home", style = MaterialTheme.typography.h6)
})

is AppDestination.Details -> Column(
modifier = Modifier.matchParentSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Details", style = MaterialTheme.typography.h6)

Text(text = "Item ${destination.itemId}", style = MaterialTheme.typography.subtitle1)
}

else -> {}
}
}
}

0 comments on commit a1149d2

Please sign in to comment.