terrakok / Cicerone

🚦 Cicerone is a lightweight library that makes the navigation in an Android app easy.
Other
2.58k stars 218 forks source link

BackTo not working for activities #100

Closed ITurchenko closed 4 years ago

ITurchenko commented 5 years ago

BackTo command doesn't work for activities in history stack.

Let's say we have Screen1 - Activity1, Screen2 - Activity2 and Screen3 - Activity3

router().newRootChain(Screen1,Screen2,Screen3)

Now we want go back from Screen3 to Screen2 But router().backTo(Screen2) will not work at all! Because backTo() method in AppNavigator works only with fragments!

kevinhao426 commented 5 years ago

Hi I'm facing the same situation yesterday, and I found that not only BackTo(), but also NavigateTo() function is not working on Activities in route tree. In this situation, I'm trying to use fragments and avoid activities in my projects. I have one idea that might solve the problem but may have some performance issues (I haven't test it yet). We can use an empty fragment as bridge to link the route tree and activities, between this fragment and activities we use startActivityForResult() and onActivityResult() to pass parameters to control routes. In this way, because the empty fragment it self is in the route tree, we can use BackTo and NavigateTo functions to implement navigation, and there is no need to directly add activities into the route tree. Also it might be required to set the activities' launch mode to single task.

Any way, I still think that it would be great to let BackTo and NavigateTo available for activities.

engi2nee commented 5 years ago

I think replace also doesn't work for activities

terrakok commented 4 years ago

Yes, this library doesn't support full featured navigation for activities because there isn't way to manipulate activities stack directly

bios90 commented 2 years ago

Just interesting why using Intent.FLAG_ACTIVITY_CLEAR_TOP when creating intent to go back to ActivityScreen is not a solution?

class MyNavigator(activity: FragmentActivity, containerId: Int) : AppNavigator(
    activity = activity,
    containerId = containerId
) {
    override fun backTo(command: BackTo) {
        if (command.screen is ActivityScreen) {
            backToActivity(command.screen as ActivityScreen)
        } else {
            super.backTo(command)
        }
    }

    private fun backToActivity(screen: ActivityScreen) {
        val activityIntent = screen.createIntent(activity)
            .apply {
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            }
        try {
            activity.startActivity(activityIntent, screen.startActivityOptions)
        } catch (e: ActivityNotFoundException) {
            unexistingActivity(screen, activityIntent)
        }
    }
}
terrakok commented 2 years ago

If there isn't the screen in the stack new screen will be launched