Closed MFlisar closed 6 years ago
Android Studio supports own code templates by default. You can find a lot of articles about the creation. I have a few base classes based on mosby library and I can create the fragment, presenter, viewstate classes only with set the feature name.
The problem with this is that every project/team will have its own set of such templates. So I think it's not something you can generalize and distribute with a library. You could make another artifact, but then again - 1 out of 5 users will use it, and 4 of them will create something different.
You can create base classes and the team/projects can it use as a submodule or library. With generics and abstract methods/variables it's possible and reduce boilerplate code.
@MFlisar, I went through a very similar line of thinking even as far as considering templates. I ended writing a generator with KotlinPoet and it has worked out fantastically. Here's an example of what my generator script looks like:
val destinationData = DestinationData("match_play.leaderboard.xxx")
val breakingNewsBanner = MviUnitInput.New("Break News Banner",
layoutType = LayoutType.LINEAR)
val liveBanner = MviUnitInput.Existing("P Cup Live Banner",
packageName = "com.tour.pgatour.dual_team.scoring.live_banner")
val matchPlayBanner = MviUnitInput.New("Match Play Banner",
layoutType = LayoutType.RELATIVE)
val tournamentHeader = MviUnitInput.Existing("P Cup Tournament Header",
packageName = "com.tour.pgatour.dual_team.scoring.tournament_model")
val weatherBroadcast = MviUnitInput.Existing("Weather And Broadcast",
packageName = "com.tour.pgatour.dual_team.scoring.weather_broadcast")
val matchPlayRoundSelector = MviUnitInput.New("Match Play Round Selector",
layoutType = LayoutType.LINEAR)
val roundPlayMatchSummaries = MviUnitInput.New("Round Play Match Summaries",
layoutType = LayoutType.RELATIVE)
val knockOutMatchSummaries = MviUnitInput.New("Knockout Match Summaries",
layoutType = LayoutType.RELATIVE)
val feature = FeatureData(featureName = "Match Play Leaderboard",
topComponentConfig = TopLevelOptionConfig(
uiOption = UiOption.FRAGMENT,
mviUnits = listOf(breakingNewsBanner,
liveBanner,
matchPlayBanner,
tournamentHeader,
weatherBroadcast,
matchPlayRoundSelector),
refreshActionBar = true,
showInterstitial = ShowInterstitial.Yes("PAGE_LEADERBOARD".toConstantsClassName())),
childComponents = listOf(
ChildOptionConfig(listOf(
roundPlayMatchSummaries
),
childFeatureName = "Round Play Match Summaries",
indexed = true),
ChildOptionConfig(listOf(
knockOutMatchSummaries
),
childFeatureName = "Knockout Match Summaries",
indexed = false)),
bundleArgs = listOf(TourCodeArg, TournamentIdArg))
FeatureGenerator(destinationData, feature).generateFeature()
This will build 5 MVI units, reference 3 existing ones, build 3 fragments, and set up a heavy amount of dependency injection for the the whole screen. I would highly recommend the approach. My coworkers use it as well and it greatly increased productivity. Here's how the actual generator portion of the module are laid out:
@jhowens89 ooh, a very interesting approach! How does one actually executes this generator? Is it some gradle task in the same project?
Pretty cool stuff, thanks for sharing. However, I would like to not add this to Mosby repo itself because I think its too much team specific, but I gladly add a link to your template generator in readme.
@jhowens89, Hi, may I try your generator as I'm setting up a new project these days?
Whenever I add a feature to my app, I see myself copying over 4 classes, which basically are all the same.
I always create 4 classes like following:
<FEATURE>Interactor
<FEATURE>Presenter
<FEATURE>State
Mvi<FEATURE>Activity
My basic copy & paste source looks like following:
It must not be exactly like my template, but it would be a nice android studio extension to be able to add default templates where you only enter "Category" in my case and the template will create 4 files like the ones above or similar.
You probably have some template you always reuse, how do you handle this? Do you always create your files manually?