Skip to content

Commit

Permalink
feat: add solution examples for popBackStack() blank screen issues
Browse files Browse the repository at this point in the history
  • Loading branch information
ImaginativeShohag committed Jun 29, 2024
1 parent 13dda76 commit 9d4e0ed
Show file tree
Hide file tree
Showing 11 changed files with 490 additions and 58 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ dependencies {
implementation(project(":tictactoe"))
implementation(project(":exoplayer"))
implementation(project(":cms"))
implementation(project(":popbackstack"))

implementation(Libs.Kotlin.stdlib)
implementation(Libs.AndroidX.coreKtx)
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@
</intent-filter>
</activity>

<activity
android:name=".popbackstack.PopBackStackActivity"
android:exported="true"
android:theme="@style/Theme.WhyNotCompose" />

<activity
android:name=".ui.screens.tutorial.deeplinks.DeepLinksActivity"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

package org.imaginativeworld.whynotcompose.ui.screens

import android.app.Activity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -38,11 +39,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.activity
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
Expand All @@ -58,6 +61,7 @@ import org.imaginativeworld.whynotcompose.cms.ui.screens.CMSMainScreen
import org.imaginativeworld.whynotcompose.exoplayer.ExoPlayerScreen
import org.imaginativeworld.whynotcompose.models.DemoData
import org.imaginativeworld.whynotcompose.models.MapPlace
import org.imaginativeworld.whynotcompose.popbackstack.PopBackStackActivity
import org.imaginativeworld.whynotcompose.tictactoe.TicTacToeScreen
import org.imaginativeworld.whynotcompose.tictactoe.TicTacToeViewModel
import org.imaginativeworld.whynotcompose.ui.screens.animation.composeone.ComposeOneScreen
Expand Down Expand Up @@ -281,6 +285,10 @@ sealed class TutorialsScreen(val route: String) {
// ================================================================

data object TutorialReactiveModel : TutorialsScreen("tutorial/reactive-model")

// ================================================================

data object TutorialPopBackStack : TutorialsScreen("tutorial/pop-back-stack")
}

// ================================================================
Expand Down Expand Up @@ -829,12 +837,20 @@ private fun NavGraphBuilder.addTutorialIndexScreen(
updateUiThemeMode: (UIThemeMode) -> Unit
) {
composable(TutorialsScreen.TutorialIndex.route) {
val context = LocalContext.current

TutorialIndexScreen(
goBack = {
navController.popBackStack()
},
navigate = { screen ->
navController.navigate(screen.route)
if (screen.route == TutorialsScreen.TutorialPopBackStack.route) {
navController.navigate(screen.route)

(context as Activity).finish()
} else {
navController.navigate(screen.route)
}
}
)
}
Expand Down Expand Up @@ -1172,6 +1188,12 @@ private fun NavGraphBuilder.addTutorialIndexScreen(
}
)
}

// ================================================================

activity(TutorialsScreen.TutorialPopBackStack.route) {
activityClass = PopBackStackActivity::class
}
}

// ================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,68 +110,82 @@ fun TutorialIndexSkeleton(
Divider(Modifier.padding(16.dp, 0.dp))
}

Column(
Modifier
.clickable {
navigate(item.route)
}
.padding(
start = 16.dp,
top = 8.dp,
end = 16.dp,
bottom = 8.dp
)
.fillMaxWidth()
) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = buildAnnotatedString {
append(item.name)
append(" ")
MenuItem(
item = item,
onClick = {
navigate(item.route)
}
)
}
}
}
}
}

withStyle(
SpanStyle(
color = item.level.color,
fontWeight = FontWeight.Bold,
fontSize = 12.sp
@Composable
private fun MenuItem(
item: Tutorial,
onClick: ()->Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier
.clickable {
onClick()
}
.padding(
start = 16.dp,
top = 8.dp,
end = 16.dp,
bottom = 8.dp
)
.fillMaxWidth()
) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = buildAnnotatedString {
append(item.name)
append(" ")

withStyle(
SpanStyle(
color = item.level.color,
fontWeight = FontWeight.Bold,
fontSize = 12.sp
)
) {
append(item.level.name.uppercase())
}
}
)

if (item.description != null) {
Text(
modifier = Modifier.padding(
top = 4.dp
),
text = buildAnnotatedString {
for (section in LiteMarkdown.getSections(item.description)) {
if (section.second) {
withStyle(
SpanStyle(
fontFamily = FontFamily.Monospace,
fontSize = 11.sp,
background = MaterialTheme.colors.onBackground.copy(
.05f
)
) {
append(item.level.name.uppercase())
}
)
) {
append(section.first)
}
)

if (item.description != null) {
Text(
modifier = Modifier.padding(
top = 4.dp
),
text = buildAnnotatedString {
for (section in LiteMarkdown.getSections(item.description)) {
if (section.second) {
withStyle(
SpanStyle(
fontFamily = FontFamily.Monospace,
fontSize = 11.sp,
background = MaterialTheme.colors.onBackground.copy(
.05f
)
)
) {
append(section.first)
}
} else {
append(section.first)
}
}
},
fontSize = 12.sp
)
} else {
append(section.first)
}
}
}
}
},
fontSize = 12.sp
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ data class Tutorial(
description = "Example of reactive model in `MVVM`.",
route = TutorialsScreen.TutorialReactiveModel,
level = TutorialLevel.Beginner
),
Tutorial(
name = "Navigation blank screen issue",
description = "Solutions for `popBackStack()` blank screen issue.",
route = TutorialsScreen.TutorialPopBackStack,
level = TutorialLevel.Intermediate
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.imaginativeworld.whynotcompose.base.extensions

import android.app.Activity
import android.content.Context
import androidx.lifecycle.Lifecycle
import androidx.navigation.NavController

/**
* Attempts to pop the controller's back stack.
* If the back stack is empty, it will finish the activity.
*
* @param context Activity context.
*/
fun NavController.popBackStackOrFinish(context: Context) {
if (!popBackStack()) {
(context as Activity).finish()
}
}

/**
* Attempts to pop the controller's back stack.
* It will check the current lifecycle and only allow the pop
* if the current state is RESUMED.
*
* See [reference](https://github.com/google/accompanist/issues/1408#issuecomment-1673011548)
*/
fun NavController.popBackStackOrIgnore() {
if (currentBackStackEntry?.lifecycle?.currentState == Lifecycle.State.RESUMED) {
popBackStack()
}
}
1 change: 1 addition & 0 deletions popbackstack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Loading

0 comments on commit 9d4e0ed

Please sign in to comment.