Issue
What is the best way to implement bottom navigation between activities that reside in different packages ? Where the packages import one another in a top down fashion.
Setup
I have structured my project as a set of packages; Essentially split into the main app
, a number of intermediate PACKAGE
s and the final end
package :
app
- Provides the main application and serves as the projects build target. It contains a single activity,Main
, providing the primary entry point for the application. The navigation graph simply maps the only fragment to theACTIVITY
's provided by each of the importedPACKAGE
's.PACKAGE
- Provides a single activity,ACTIVITY
, to manage a dedicated task. The navigation graph manages the relationships between the various fragments supporting the activity; Additionally it includes link to theFinal
activity imported fromend
.end
- Provides a single activity,Final
, which eachPACKAGE
importing it uses as the terminating navigation link for their navigation graphs.
So each package contains a single activity, one or more fragments and a navigation graph that manages the routing between them and a node pointing to the activity in the next package in the order app.Main > PACKAGE.ACTIVITY > end.Final
.
Navigation
Given this structure I want to add bottom navigation, |Main|...|Final|
, to each activity ACTIVITY
such that there is a link back to Main
and another onward to Final
. Linking forward to Final
is easy enough as enough as it's already a target in each PACKAGE
s navigation graph but I am uncertain on the best method for linking back to Main
. Similarly I want to provide bottom navigation, |Main|ACTIVITY|...|
, to Final
such that the user go back to either the preceding ACTIVITY
or Main
.
Considerations
What is the best means of providing navigation targets to the activities in the parent packages ? To me the following seem viable
- Cross import all of the packages within gradle. That is
app
imports eachPACKAGE
andend
, everyPACKAGE
imports bothapp
andend
, andend
imports eachPACKAGE
andapp
. This is not very DRY but it will make all activities universally accessible. - Pass
Main
as a list toACTIVITY
, adding it to the navigation menu programatically. Similarly passMain
andACTIVITY
as a list toFinal
. Here I'm not sure, given that activites have lifecycles, if I should pass the activity class or the instance thereof to the child activity ? The advantage here is that I can readily create the backstack if it's missing. - Interrogate the "Activity" back stack as it already details the route to both
ACTIVITY
(That is it containsMain
) andFinal
(That is it containsMain
andACTIVITY
). Here it becomes tricky to create the backstack after the fact. - Use deep linking ? (I'm still reading up on this)
- Should one simply cross reference each activity setting
parentAttribute
under the<activity/>
in eachPACKAGES
'smanifest.xml
to provide the necessary navigation targets ? Here I'm not sure how best to add this to the bottom navigation graph/menu ? Also it becomes necessary to programmatically set theparentAttrbiute
depending upon the route taken to reachFinal
.
- Cross import all of the packages within gradle. That is
Depending on how access to the activities is provided in 1 I'm not sure what the best means is of making such target accessible ?
- Can this be done within a navigation graph ? Can I programmatically add activities from a parent package to the navigation graph ? Can a
Placeholder
be used to reference such items ? Can a custom navigation destination can be written to represent such items. - Should one simply populate the menu provided to the navigation menu used by
BottomNavigationView
? Can one do this and support targets provided by a navigation graph, that is can one overwrite bothOnNavigationItemSelectedLsitener
and usesetupWithNavController
together ?
- Can this be done within a navigation graph ? Can I programmatically add activities from a parent package to the navigation graph ? Can a
Note : While I have seen some similar questions and answers I haven't seen any that deal with activities in separate packages.
Solution
I solved this problem by interrogating the package manager to determine the activities that are available within my application, under my package name.
Adding metadata to each activity, under the MANIFEST.xml
, allowed me to filter the activities I wanted to reference. Adding android:label
and android:icon
attributes allowed me to provide labels and icons for the buttons in the navigation view and to display them upon the app bar. Furthermore I could create intents for each activity and set these upon the menu items (One of the android docs mentioned that any menuItem that is not handled directly will have its intent attribute invoked).
I wrapped all of this into an interface and can now tack that onto the activities I wish to navigate too outside of the navigation graphs supported by the navigation components.
Note : It's possible deep links serve this purpose but I haven't seena nice example just yet.
Answered By - Carel
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.