AndroidStudio4.1 自定義模板的使用方法
AndroidStudio4.0之前,可以在template的文件夾里使用freemarker的自定義模板,可以在AndroidStudio的文件夾中,隨意的添加適合自己的自定義模板
但是從4.1版本開始提供新的方式,Geminio,用Kotlin的形式編寫新的template,而且需要使用插件的形式,才能使用自定義的模板,摸索了好幾天,終于解決了。
我的項(xiàng)目是使用MVVM的開發(fā)框架,每次在編寫一個(gè)新的頁(yè)面的時(shí)候,就需要新建四個(gè)文件Activity/Fragment, ViewModel, Repository, xml文件,寫的多了就會(huì)很煩。自從使用了自定義的模板以后,頭發(fā)掉得都少了。
開工!??!搞起?。。?/p>
準(zhǔn)備
開發(fā)工具 AndroidStudio4.1
模板基礎(chǔ)代碼配置

打開 https://github.com/JetBrains/intellij-platform-plugin-template,點(diǎn)擊綠色的#Use this template#,按步驟在自己的github上創(chuàng)建模板。
然后使用AndroidStudio 將模板下載到本地。
編碼
添加wizard-template.jar
在根目錄里添加lib文件夾,并添加AndroidStudio安裝目錄里的wizard-template.jar,位于 /Applications/Android\ Studio.app/Contents/plugins/android/lib/目錄下。
修改build.gradle.kts
在dependencies里添加wizard-template.jar的依賴
dependencies {
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.15.0")
compileOnly(files("lib/wizard-template.jar"))
}
修改gradle.properties
修改gradle.properties中的pluginGroup, pluginName_, platformPlugins, platformVersion。
pluginGroup = com.bigaddemo.mvvm pluginName_ = bigaddemo_MVVM platformVersion = 2020.2 platformPlugins = java, com.intellij.java, org.jetbrains.android, android, org.jetbrains.kotlin
將默認(rèn)的listeners的父包名,調(diào)整為自己想要的樣子,例如com.company.app
修改MyProjectManagerListener
internal class MyProjectManagerListener : ProjectManagerListener {
override fun projectOpened(project: Project) {
projectInstance = project
project.getService(MyProjectService::class.java)
}
override fun projectClosing(project: Project) {
projectInstance = null
super.projectClosing(project)
}
companion object {
var projectInstance: Project? = null
}
}
在src/main/kotlin里創(chuàng)建other文件夾用于放置自定義模板

正式開始編寫自定義模板,以Activity為例。
1. 實(shí)現(xiàn)WizardTemplateProvider
SamplePluginTemplateProviderImpl
package other
import com.android.tools.idea.wizard.template.Template
import com.android.tools.idea.wizard.template.WizardTemplateProvider
import other.mvvm.activity.mvvmActivityTemplate
import other.mvvm.fragment.mvvmFragmentTemplate
class SamplePluginTemplateProviderImpl : WizardTemplateProvider() {
override fun getTemplates(): List<Template> = listOf(
// activity的模板
mvvmActivityTemplate,
// fragment的模板
mvvmFragmentTemplate
)
}
2. 創(chuàng)建 mvvmActivityTemplate.kt.
這個(gè)文件是設(shè)置在創(chuàng)建Activity的時(shí)候,輸入的信息,例如ActivityName,layoutName,packageName以及是否可以為為等
mvvmActivityTemplate.kt
package other
import com.android.tools.idea.wizard.template.Template
import com.android.tools.idea.wizard.template.WizardTemplateProvider
import other.mvvm.activity.mvvmActivityTemplate
import other.mvvm.fragment.mvvmFragmentTemplate
class SamplePluginTemplateProviderImpl : WizardTemplateProvider() {
override fun getTemplates(): List<Template> = listOf(
// activity的模板
mvvmActivityTemplate,
// fragment的模板
mvvmFragmentTemplate
)
}
3. 創(chuàng)建mvvmActivityRecipe.kt。
這個(gè)文件用于將創(chuàng)建的文件保存到文件夾中,例如Activity,布局文件等。 原計(jì)劃將Activity直接添加到AndroidManifest里,但是發(fā)現(xiàn)generateManifest有點(diǎn)問(wèn)題,導(dǎo)致生成的插件不能使用,暫時(shí)去掉,只能手動(dòng)添加了。
mvvmActivityRecipe.kt
package other.mvvm.activity
import com.android.tools.idea.wizard.template.ModuleTemplateData
import com.android.tools.idea.wizard.template.RecipeExecutor
import other.mvvm.activity.res.layout.mvvmActivityXml
import other.mvvm.activity.src.app_package.mvvmAcitivityKt
import other.mvvm.activity.src.app_package.mvvmRepository
import other.mvvm.activity.src.app_package.mvvmViewModel
fun RecipeExecutor.mvvmActivityRecipe(
moduleData: ModuleTemplateData,
activityClass: String,
layoutName: String,
packageName: String
) {
val (projectData, srcOut, resOut) = moduleData
val ktOrJavaExt = projectData.language.extension
// generateManifest(
// moduleData = moduleData,
// activityClass = "${activityClass}Activity",
// activityTitle = activityClass,
// packageName = packageName,
// isLauncher = false,
// hasNoActionBar = false,
// generateActivityTitle = true,
// requireTheme = false,
// useMaterial2 = false
// )
val mvvmActivity = mvvmAcitivityKt(projectData.applicationPackage, activityClass, layoutName, packageName)
// 保存Activity
save(mvvmActivity, srcOut.resolve("${activityClass}Activity.${ktOrJavaExt}"))
// 保存xml
save(mvvmActivityXml(packageName, activityClass), resOut.resolve("layout/${layoutName}.xml"))
// 保存viewmodel
save(mvvmViewModel(packageName, activityClass), srcOut.resolve("${activityClass}ViewModel.${ktOrJavaExt}"))
// 保存repository
save(mvvmRepository(packageName, activityClass), srcOut.resolve("${activityClass}Repository.${ktOrJavaExt}"))
}
4. 創(chuàng)建mvvmAcitivityKt。
這個(gè)文件用于創(chuàng)建Activity的模板代碼,根據(jù)自己的情況,自行調(diào)整。
mvvmAcitivityKt.kt
package other.mvvm.activity.src.app_package
fun mvvmAcitivityKt(
applicationPackage:String?,
activityClass:String,
layoutName:String,
packageName:String
)="""
package ${packageName}
import android.os.Bundle
import com.bigademo.baselib.base.BaseActivity
import ${applicationPackage}.R
import ${applicationPackage}.BR;
import ${applicationPackage}.databinding.Activity${activityClass}Binding
class ${activityClass}Activity : BaseActivity<${activityClass}ViewModel, Activity${activityClass}Binding>() {
override fun getContentView(): Int {
return R.layout.${layoutName}
}
override fun init(savedInstanceState: Bundle?) {
super.init(savedInstanceState)
isShowTopBar = false
}
override fun initViewModel() {
viewModel = ${activityClass}ViewModel()
}
/**
* 監(jiān)聽數(shù)據(jù)的變化
*/
override fun observe() {
}
/**
* 控件的點(diǎn)擊事件
*/
override fun onClick() {
}
override fun initData() {
super.initData()
}
override fun initVariableId(): Int {
TODO("Not yet implemented")
}
}
"""
5. 編寫mvvmRepository。
這個(gè)文件是mvvm的repository層的代碼。
mvvmRepository.kt
package other.mvvm.activity.src.app_package
fun mvvmRepository(
packageName:String,
activityClass:String
)="""
package ${packageName}
import androidx.lifecycle.MutableLiveData
import com.shide.baselib.base.basemvvm.BaseRepository
import com.shide.baselib.base.basemvvm.BaseViewModel
import com.shide.baselib.net.exception.ShideApiException
import kotlinx.coroutines.CoroutineScope
class ${activityClass}Repository(
baseViewModel: BaseViewModel,
coroutineScope: CoroutineScope,
errorLiveData: MutableLiveData<ShideApiException>
) : BaseRepository(baseViewModel, coroutineScope, errorLiveData) {
}
"""
6. 編寫mvvmViewModel。這個(gè)是mvvm的viewmodel層 mvvmViewModel.kt
package other.mvvm.activity.src.app_package
fun mvvmViewModel(
packageName:String,
activityClass:String
)="""
package ${packageName}
import androidx.lifecycle.viewModelScope
import com.bigademo.baselib.base.basemvvm.BaseViewModel
class ${activityClass}ViewModel : BaseViewModel() {
private val repo by lazy { ${activityClass}Repository(this, viewModelScope, errorLiveData) }
}
"""
7.編寫mvvmActivityXml。這個(gè)文件是用于生成布局文件的 mvvmActivityXml.kt
package other.mvvm.activity.res.layout
fun mvvmActivityXml(
packageName: String,
activityClass: String
) = """
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}Activity">
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
8. 修改plugin.xml
添加org.jetbrains.android,org.jetbrains.kotlin,com.intellij.modules.java的依賴
修改applicationService和projectService的值
修改applicationListenersv中l(wèi)istener的值
添加wizardTemplateProvider為剛才添加的類
<idea-plugin> <id>com.bigaddemo.mvvm</id> <name>bigaddemo_MVVM</name> <vendor>bigademo</vendor> <!-- Product and plugin compatibility requirements --> <!-- https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html --> <depends>org.jetbrains.android</depends> <depends>org.jetbrains.kotlin</depends> <depends>com.intellij.modules.java</depends> <depends>com.intellij.modules.platform</depends> <extensions defaultExtensionNs="com.intellij"> <applicationService serviceImplementation="com.bigaddemo.mvvm.services.MyApplicationService" /> <projectService serviceImplementation="com.bigaddemo.mvvm.services.MyProjectService" /> </extensions> <applicationListeners> <listener class="com.bigaddemo.mvvm.listeners.MyProjectManagerListener" topic="com.intellij.openapi.project.ProjectManagerListener" /> </applicationListeners> <extensions defaultExtensionNs="com.android.tools.idea.wizard.template"> <wizardTemplateProvider implementation="other.SamplePluginTemplateProviderImpl" /> </extensions> </idea-plugin>
生成jar文件
在AS最上面選擇運(yùn)行 Run plugin ,成功以后即可在build/libs找見對(duì)應(yīng)的jar文件。最后在AS的設(shè)置里將這個(gè)jar包添加的plugin,重啟AS即可。

到此這篇關(guān)于AndroidStudio4.1 自定義模板的使用方法的文章就介紹到這了,更多相關(guān)AndroidStudio4.1 自定義模板內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)類似iOS風(fēng)格的對(duì)話框?qū)嵗a
通過(guò)本文給大家分享一個(gè)簡(jiǎn)單的常用的對(duì)話框類,關(guān)于Android實(shí)現(xiàn)類似iOS風(fēng)格的對(duì)話框?qū)嵗a大家通過(guò)本文學(xué)習(xí)下吧2017-09-09
OpenHarmony如何調(diào)用電話服務(wù)API撥打電話
OpenHarmony3.1版本標(biāo)準(zhǔn)系統(tǒng)增加了通話相關(guān)的聯(lián)系人應(yīng)用,來(lái)電應(yīng)用等,在系統(tǒng)服務(wù)層面電話相關(guān)功能也比較完善,這篇文章主要介紹了OpenHarmony如何調(diào)用電話服務(wù)API撥打電話2022-11-11
Android編程開發(fā)之ScrollView嵌套GridView的方法
這篇文章主要介紹了Android編程開發(fā)之ScrollView嵌套GridView的方法,結(jié)合實(shí)例分析了ScrollView嵌套GridView的相關(guān)注意事項(xiàng)與處理技巧,需要的朋友可以參考下2015-12-12
android多媒體音樂(lè)(MediaPlayer)播放器制作代碼
這篇文章主要為大家詳細(xì)介紹了android多媒體音樂(lè)(MediaPlayer)播放器的制作相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼
這篇文章主要介紹了Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
Android TextView實(shí)現(xiàn)多文本折疊、展開效果
這篇文章主要為大家詳細(xì)介紹了Android TextView實(shí)現(xiàn)多文本折疊、展開效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
android中強(qiáng)制更新app實(shí)例代碼
本篇文章主要介紹了android中強(qiáng)制更新app實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05

