Skip to content

Instantly share code, notes, and snippets.

@alizeec
Created February 11, 2020 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alizeec/8f37b636ba31a0cbc60af504603f8291 to your computer and use it in GitHub Desktop.
Save alizeec/8f37b636ba31a0cbc60af504603f8291 to your computer and use it in GitHub Desktop.
Old navigation system at Aircall
interface INavigatorProvider {
fun of(baseActivity: BaseActivity): IInternalNavigator
fun of(appContext: Context): IExternalNavigator
}
interface INavigator {
fun buildIntent(routeOptions: RouteOptions, extras: Bundle?): Intent
}
interface IExternalNavigator : INavigator {
fun startActivity(intent: Intent)
fun openEmailApplication(intent: Intent, title: String)
}
interface IInternalNavigator : INavigator {
fun navigate(routeOptions: RouteOptions, extras: Bundle?)
fun navigateForResult(routeOptions: RouteOptions, requestCode: Int, extras: Bundle?)
fun navigateUp(): Boolean
fun navigateUpForResultOk(intent: Intent?)
fun findCurrentFragment(): Fragment?
}
interface IRouteParser {
fun parseRoute(route: String, clearTask: Boolean): RouteOptions?
}
interface IRouter {
var currentBaseActivity: BaseActivity?
fun navigateTo(route: String, clearTask: Boolean = false, extras: Bundle? = null)
fun navigateForResult(route: String, requestCode: Int, extras: Bundle? = null)
fun openExternalApplication(
appType: ExternalAppType,
toEmails: Array<out String> = emptyArray(),
subject: String? = null,
text: String? = null,
title: String
)
fun navigateBack()
fun navigateUpForResultOk(intent: Intent?)
fun getCurrentView(): Fragment?
fun setCurrentActivity(activity: BaseActivity)
fun unSetCurrentActivity(activity: BaseActivity)
}
MyPresenter {
...
router.navigateTo(Routes.SIGN_IN_FORM, clearTask = true)
...
}
class AndroidNavigatorProvider @Inject constructor() : INavigatorProvider {
override fun of(baseActivity: BaseActivity) = NavComponentNavigator(baseActivity)
override fun of(appContext: Context) = ExternalNavigator(appContext)
}
class ExternalNavigator(private val appContext: Context) : IExternalNavigator {
override fun buildIntent(routeOptions: RouteOptions, extras: Bundle?): Intent {
...
return intent
}
override fun startActivity(intent: Intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
appContext.startActivity(intent)
}
override fun openEmailApplication(intent: Intent, title: String) { ... }
}
class NavComponentNavigator(private val baseActivity: BaseActivity) : IInternalNavigator {
private val navController: NavController =
Navigation.findNavController(baseActivity, baseActivity.getFragmentHostId())
override fun navigate(routeOptions: RouteOptions, extras: Bundle?) {
val bundle = bundleOf(RoutingConstants.EXTRA_ROUTE_PARAM to routeOptions.routeType.param)
extras?.let {
bundle.putAll(it)
}
routeOptions.run {
if (clearTask) findCurrentFragment()?.activity?.finish()
navController.navigate(routeType.destinationId, bundle)
}
}
override fun navigateForResult(routeOptions: RouteOptions, requestCode: Int, extras: Bundle?) {
routeOptions.run {
// startActivityForResult() from fragment context
findCurrentFragment()?.startActivityForResult(
Intent(baseActivity, routeOptions.destinationActivityClass).apply {
if(extras != null){
putExtras(extras)
}
},
requestCode
) ?:
// startActivityForResult() from activity context
baseActivity.startActivityForResult(
Intent(baseActivity, routeOptions.destinationActivityClass).apply {
if(extras != null){
putExtras(extras)
}
},
requestCode
)
}
}
override fun navigateUp() = navController.navigateUp()
override fun navigateUpForResultOk(intent: Intent?) {
intent?.let {
baseActivity.setResult(Activity.RESULT_OK, it)
} ?: baseActivity.setResult(Activity.RESULT_OK)
}
override fun findCurrentFragment(): Fragment? {
val navHostFragment = baseActivity.supportFragmentManager.findFragmentById(baseActivity.getFragmentHostId())
if (navHostFragment is NavHostFragment) {
return navHostFragment.childFragmentManager.fragments[0]
}
return null
}
}
class RouteParser @Inject constructor() : IRouteParser {
override fun parseRoute(route: String, clearTask: Boolean): RouteOptions? {
return when (route) {
Routes.SPLASH -> RouteOptions(
RouteType(route, R.id.fragment_splash_screen),
SplashScreenActivity::class.java,
clearTask
)
...
}
}
}
data class RouteOptions(
val routeType: RouteType,
val destinationActivityClass: Class<out Activity>,
val clearTask: Boolean = false
)
object Router : IRouter {
override var currentActivity: BaseActivity? = null
@set:Inject
lateinit var routeParser: IRouteParser
@set:Inject
lateinit var navigatorProvider: INavigatorProvider
@set:Inject
lateinit var applicationContext: Context
override fun navigateTo(route: String, clearTask: Boolean, extras: Bundle?) {
routeParser.parseRoute(route, clearTask)?.let { routeOptions ->
currentActivity?.also { activity ->
navigatorProvider.of(activity).navigate(routeOptions, extras)
} ?: run {
with(navigatorProvider.of(applicationContext)) {
startActivity(buildIntent(routeOptions, extras))
}
}
}
}
override fun navigateForResult(route: String, requestCode: Int, extras: Bundle?) {
routeParser.parseRoute(route, false)?.let { routeOptions ->
currentActivity?.also { activity ->
navigatorProvider.of(activity).navigateForResult(routeOptions, requestCode, extras)
}
}
}
override fun openExternalApplication(...) {
when (appType) {
ExternalAppType.EMAIL -> openEmailApp(toEmails, subject, text, title)
ExternalAppType.SHARE -> openSharingTextPanel(text)
}
}
private fun openEmailApp(...) { ... }
private fun openSharingTextPanel(...) { ... }
override fun navigateBack() {
currentActivity?.let {
if (!navigatorProvider.of(it).navigateUp()) {
it.finish()
}
}
}
override fun navigateUpForResultOk(intent: Intent?) {
currentActivity?.let {
navigatorProvider.of(it).navigateUpForResultOk(intent)
it.finish()
}
}
override fun getCurrentView(): Fragment? {
currentActivity?.let { activity ->
return navigatorProvider.of(activity).findCurrentFragment()
}
return null
}
override fun setCurrentActivity(activity: BaseActivity) { ... }
override fun unSetCurrentActivity(activity: BaseActivity) { ... }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment