Android Studio 代码模板插件实现

这篇具有很好参考价值的文章主要介绍了Android Studio 代码模板插件实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android Studio 代码模板插件

背景

可以跳过背景和简述,从模板插件实现开始看.

开发新页面时,原先需要写一堆模板代码。比如用Databinding写列表结构的页面,需要手写以下文件:

  • XxActivity.kt
  • XxFragment.kt
  • XxViewModel.kt
  • XxListAdapter.kt
  • XxListItemModel.kt(UI数据结构)
  • XxBean.kt(接口数据结构)
  • XxBeanModelConvert.kt
  • XxRetrofitApi.kt
  • XxRetrofitRepository.kt
  • yymoudle_xx_layout_activity.xml
  • yymoudle_xx_layout_fragment.xml
  • yymoudle_xx_layout_list_item.xml(列表item)

并且类文件间还有相互的引用关系。

如果能有一套代码模板,可以一键生成最小单元功能代码,确实能提高新开发页面的效率。(加快1~2个小时不为过吧?)

简述

Android Studio Editor

Android Studio 自带了两种代码模板(入口为Settings -> Edit):

  • File and Code Templates : 倾向生成单个文件
  • Live Templates :在单个文件中快捷生成代码,例如logd生成Log.d(TAG, String)

File and Code Templates 和Live Templates
Android Studio 代码模板插件实现,android studio

Android Studio Plugin

于是把目光投向了代码模板插件,搜索template,可以看到很多,比如这个Jetpack Compose UI Architecture Plugin

Android Studio 代码模板插件实现,android studio

Android Studio 代码模板插件实现,android studio

如何我实现自己的代码模板插件?

模板插件实现

Android Studio 是基于 IntelliJ IDEA开发的,Android Studio可以使用IntelliJ上丰富的插件。
IntelliJ提供了一个用于创建模板代码插件的模板项目,基于这个模板项目改造 。

最终效果

选择模板 -> 模板配置 -> 生成代码

选择模板
Android Studio 代码模板插件实现,android studio
模板配置
Android Studio 代码模板插件实现,android studio
生成代码
Android Studio 代码模板插件实现,android studio

插件工程的创建与配置

工程创建

模板项目仓库地址:
https://github.com/JetBrains/intellij-platform-plugin-template

按照步骤 Use this template-> Create a new repository 在自己的github下生成仓库。

这是我生成的项目仓库地址:https://github.com/AlvinScrp/android-code-template

Android Studio 代码模板插件实现,android studio

修改配置

用Android Studio打开这个项目,先修改一波基础配置,修改内容的commit:
https://github.com/AlvinScrp/android-code-template/commit/c0eaaa9c7a5451f29efb1b5f91eec131568d5f89

注意:要导入Android代码模板需要的 wizard-template.jar, 其实是从Android Studio目录/plugins/android/lib中复制过来的。

模板插件代码编写

generator包下都是我们新写的代码,代码调用顺序为

PluginGeneratorProvider.kt -> Generator.kt -> Recipe.kt

Android Studio 代码模板插件实现,android studio

PluginGeneratorProvider

对应【选择模板】界面

package com.github.alvinscrp.androidcodetemplate.generator  
  
import com.android.tools.idea.wizard.template.Template  
import com.android.tools.idea.wizard.template.WizardTemplateProvider  
import com.github.alvinscrp.androidcodetemplate.generator.mvvm.jlMvvmGenerator  
import com.github.alvinscrp.androidcodetemplate.generator.util.AppType  
  
  
class PluginGeneratorProvider : WizardTemplateProvider() {  
  
    override fun getTemplates(): List<Template> = listOf(  
        //这里建了三套模板
        jlMvvmGenerator(AppType.FXJ),  
        jlMvvmGenerator(AppType.HYK),  
        jlMvvmGenerator(AppType.MC)  
    )  
}

Android Studio 代码模板插件实现,android studio

在plugin.xml中注册该provider

<extensions defaultExtensionNs="com.android.tools.idea.wizard.template">  
<wizardTemplateProvider implementation="com.github.alvinscrp.androidcodetemplate.generator.PluginGeneratorProvider" />  
</extensions>
Generator.kt
package com.github.alvinscrp.androidcodetemplate.generator.mvvm  
  
import com.android.tools.idea.wizard.template.*  
import com.android.tools.idea.wizard.template.impl.activities.common.MIN_API  
import com.github.alvinscrp.androidcodetemplate.generator.util.AppType  
  
/**  
* 模板配置需要的参数,根据你的需要,在这里添加  
*/
fun jlMvvmGenerator(appType: AppType): Template {  
  
    return template {  
        name = "DataBinding Mvvm Temp Code - ${appType.key}"  
        description =  
    "生成一套基于DataBinding的MVVM代码,包括:Activity、Fragment、ViewModel、ListAdapter、 ListItemModel、BeanModelConvert、Bean、 Retrofit Api、 Repository"  
        minApi = MIN_API  
  
        category = Category.Other  
        formFactor = FormFactor.Mobile  
        screens = listOf(  
            WizardUiContext.ActivityGallery,  
            WizardUiContext.MenuEntry,  
            WizardUiContext.NewProject,  
            WizardUiContext.NewModule)  
            
        val bizNameParameter = stringParameter {  
            name = "Business Name:英文,小写开头,camel命名,可以多单词"  
            default = "template"  
            help = "业务名称:英文,可以多单词,camel命名,用来作为生成的各种文件的前缀"  
            constraints = listOf(Constraint.NONEMPTY)  
        }  
    
        val classPackageNameParameter = stringParameter {  
            name = "Class Package Name: 这个不要改它"  
            help = "文件名称:生成文件的存放位置,不是APP包名"  
            default = "com.github.alvinscrp"  
            constraints = listOf(Constraint.PACKAGE)  
            suggest = { packageName }  
        }  

        val isCreateActivityParameter = booleanParameter {  
            name = "生成Activity,需手动加入清单文件"  
            help = ""  
            default = false  
        }  
 
       widgets(  
            TextFieldWidget(bizNameParameter),  
            TextFieldWidget(classPackageNameParameter),    
            CheckBoxWidget(isCreateActivityParameter)  
        )  
  
        recipe = {  
            mvvmRecipe(  
                it as ModuleTemplateData,  
                bizNameParameter.value,  
                classPackageNameParameter.value,   
                appType,  
                isCreateActivityParameter.value  
            )  
        }  
    }  
}

对应【模板配置】界面
Android Studio 代码模板插件实现,android studio

Recipe.kt
package com.github.alvinscrp.androidcodetemplate.generator.mvvm  
  
  
import com.android.tools.idea.wizard.template.ModuleTemplateData  
import ... 
  
/**  
* 模板代码文件的创建与保存  
* 这里有几个变量需要注意下:  
* ```
* //当前批量生成类文件所在目录 com.example.x.y
* classPackageName : String
*
* //模块名,例如 user
* val moduleName = moduleData.rootDir.name.toLowerCaseAsciiOnly()
*
* //模块包名,例如com.example.user , 在模块AndroidManifest.xml中配置的那个,一定要注意
* val modulePackageName = projectData.applicationPackage
* ```
*/  
fun RecipeExecutor.mvvmRecipe(  
moduleData: ModuleTemplateData,  
bizName: String,  
classPackageName: String,  
appType: AppType,  
isCreateActivity: Boolean  
) {  
val (projectData, srcOut, resOut) = moduleData  
val moduleName = moduleData.rootDir.name.toLowerCaseAsciiOnly()  
val modulePackageName = projectData.applicationPackage ?: ""

    // println("---->${projectData.rootDir},${projectData.applicationPackage},${moduleData.rootDir.name},${moduleData.packageName}")  
  
    if(isCreateActivity) {  
        save(  
            mvvmActivityTemp(appType, modulePackageName, classPackageName, moduleName, bizName),  
        srcOut.resolve("${bizName}/ui/${firstUppercase(bizName)}Activity.kt")  
        )
    //插入Manifest ,这个代码运行报错,反正我也用不到,就不管了
    // generateManifest(  
        // moduleData = moduleData,  
        // activityClass = "${firstUppercase(bizName)}Activity",  
        // packageName = "${classPackageName}.${bizName}.ui",  
        // isLauncher = false,  
        // hasNoActionBar = false,  
        // isNewModule = false,  
        // isLibrary = false,  
        // generateActivityTitle = false  
    // )
    }  
    save(  
        mvvmFragmentTemp(appType, modulePackageName, classPackageName,moduleName, bizName),  
        srcOut.resolve("${bizName}/ui/${firstUppercase(bizName)}Fragment.kt")  
    )  
    
    ......代码较多,省略 
    save(  
        fragmentLayoutTemp(appType,classPackageName, bizName),  
        resOut.resolve("layout/${fragmentLayoutName(moduleName, bizName)}.xml")  
    )  
}
xxTemp.kt

每个temp function都对应一个目标代码文件。
我们可以先在业务项目里,写一套可运行的Template代码。 插件可以基于这套Template代码修改。
以ActivityTemp.kt举例

package com.github.alvinscrp.androidcodetemplate.generator.mvvm.temp  
  
import com.github.alvinscrp.androidcodetemplate.generator.util.AppType  
import com.github.alvinscrp.androidcodetemplate.generator.util.activityLayoutName  
import com.github.alvinscrp.androidcodetemplate.generator.util.firstUppercase  
import com.github.alvinscrp.androidcodetemplate.generator.util.fragmentClassName  
  
/**  
* 生成XxActivity文件的内容,你的项目里是啥,就是啥,不要用我这个模板  
*/  
fun mvvmActivityTemp(  
    appType: AppType,  
    modulePackageName: String,  
    classPackageName: String,  
    moduleName: String,  
    bizName: String  
): String {  
return """  
    package ${classPackageName}.${bizName}.ui  
  
    import android.os.Bundle  
    import ${appType.fullBaseActivity()}  
    import ${modulePackageName}.R  
  
    class ${firstUppercase(bizName)}Activity : ${appType.simpleBaseActivity()}() {  
  
        override fun onCreate(savedInstanceState: Bundle?) {  
            super.onCreate(savedInstanceState)  
            setContentView(R.layout.${activityLayoutName(moduleName, bizName)})  
            replaceFragment(R.id.fragment_container, ${fragmentClassName(bizName)}.newInstance(123), false)  
        }  
    }  
""".trimIndent()  
}
TemplUtils.kt

在编写Temp代码时,发现有些地方还是要注意的

  • class名:大写开头
  • layout.xml文件名:小写字母+下划线
  • xxDataBinding,通过layout.xml文件名来转换,更方便.

wizard-template.jar提供了很多的方法给我们,例如:camelCaseToUnderlines()underscoreToLowerCamelCase()underscoreToCamelCase()等等

package com.github.alvinscrp.androidcodetemplate.generator.util  
  
import com.android.tools.idea.wizard.template.camelCaseToUnderlines  
import com.android.tools.idea.wizard.template.underscoreToCamelCase  
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly  
  
/**  
* 形式 ab_cd_ef 必须都是小写,以下划线连接  
*/  
fun layoutPrefix(moduleName: String, bizName: String): String {  
    return "${moduleName.toLowerCaseAsciiOnly()}_${camelCaseToUnderlines(bizName).toLowerCaseAsciiOnly()}_template"  
}     
fun fragmentLayoutName(moduleName: String, bizName: String): String {  
    return "${layoutPrefix(moduleName,bizName)}_fragment"  
}    
/**  
* moduleName 可能出现的形式 user、 User 、 UserCenter 、User_Center 、 UserCenter_kkk  
* 因为要作为布局文件名的前缀,必须都转成小写  
*/  
fun fragmentDataBindingName(moduleName: String, bizName: String): String {  
    val layoutPrefix = layoutPrefix(moduleName, bizName)  
    //sd_te --> SdTe  
    var camelCaseName = underscoreToCamelCase(layoutPrefix)  
    return "${camelCaseName}FragmentBinding"  
}  
fun firstUppercase(param: String): String {  
    return param.replaceFirstChar { it.uppercase() }  
}

模板插件测试

代码写完,就可以测试插件效果了,AndroidStudio工具栏运行Run Plugin

Android Studio 代码模板插件实现,android studio

如果可以正常编译,会自动打开一个IntelliJ IDEA窗口。

此时,可以 New Project 或者 Open 现有APP项目。

最后,按照【选择模板 -> 模板配置 -> 生成代码】的顺序,就可以生成代码了。

Android Studio 代码模板插件实现,android studio

模板插件导出与安装

通过上面的测试,你发现,写的插件很好用, "赋能"项目,如下步骤:

  • 导出插件jar:位置 build/libs/android-code-template-0.0.1.jar。

  • 导入到Android Studio的plugins:Settings -> Plugins -> Install Plugin from Disk…

Android Studio 代码模板插件实现,android studio文章来源地址https://www.toymoban.com/news/detail-610488.html

到了这里,关于Android Studio 代码模板插件实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio 插件 ChatGPT

    一、为什么要在AS里使用ChatGPT 在AS里使用ChatGPT可以辅助生成一些重复性、解析类的代码,还有一些功能性问题查找,具体需要个人探索。 官网使用经常性出现断连,需要刷新浏览器,而且经常历史列表丢失(个人是这样的,不知道大家是不是一样),这个断连比较少,重连

    2023年04月18日
    浏览(46)
  • Android Studio单独开一个线程循环执行模板

      注意:这种方式虽然能够实现循环执行,但其实没有新开线程。如果对于可能多线程出现线程阻塞的任务,需要使用在Java中多线程的方法,参考:Android studio多线程模板

    2024年02月11日
    浏览(93)
  • Android Studio使用lombok插件

    1,使用android studio,在插件中检索lombok下载安装。 2,build.gradle导入依赖 implementation \\\'org.projectlombok:lombok:1.18.8\\\' annotationProcessor \\\'org.projectlombok:lombok:1.18.8\\\' 3,使用 //通过注解方式来使用此插件 @AllArgsConstructor全参构造 @NoArgsConstructor//无参构造 @Data//get set 4, lombok简介_晓风残月( ̄

    2024年02月08日
    浏览(38)
  • Android studio配置OpenCV的JNI接口,实现C++代码编程

    目录 一、下载OpenCV-android-sdk 二、新建项目 三、导入OpenCV包  四、配置OpenCV的JNI接口,拷贝OpenCV所需的头文件和库文件 五、修改Cmake文件  六、配置app的build.gradle文件  七、测试 OpenCV官网地址:https://opencv.org/  点击Library--Releases,下载Android版本,解压得到 OpenCV-android-sdk文件

    2024年02月10日
    浏览(49)
  • Android Studio 和 Android Gradle 插件的已知问题

    渲染 Compose 预览时出错 从 Android Studio Chipmunk 开始,如果您在问题面板中看到  java.lang.NoSuchFieldError: view_tree_saved_state_registry_owner  或  java.lang.ClassNotFoundException: androidx.savedstate.R$id ,请务必在模块中添加对  androidx.lifecycle:lifecycle-viewmodel-savedstate  的  debugImplementation  依赖项。

    2024年02月12日
    浏览(52)
  • Android Studio 中使用uiautomatorviewer插件

    Android Studio是Google官方提供的一款用于 开发Android应用程序 的集成开发环境(IDE),它基于IntelliJ IDEA开发而来,为开发者提供了完整的工具链,包括代码编写、调试、测试、性能优化等。 Android Studio集成开发环境具有以下特点: 提供强大的布局编辑器 :Android Studio提供了强大

    2024年04月11日
    浏览(35)
  • Android studio Gradle 插件版本修改

      最近装了预览版的 Android Studio( android-studio-2022.3.1.15 Giraffe ),新建项目后想修改 Gradle 插件版本,在网上搜索到的都是说修改 classpath 但是新建的项目 build.gradle 中内容并不是这样的,如下: 看了官网文档,内容虽然不一样,但是修改 Gradle 版本还是在这里。 Android Gra

    2024年02月11日
    浏览(64)
  • 蓝牙App设计2:使用Android Studio制作一个蓝牙软件(包含:代码实现等)

    前言:蓝牙聊天App设计全部有三篇文章(一、UI界面设计,二、蓝牙搜索配对连接实现,三、蓝牙连接聊天),这篇文章是:二、蓝牙搜索配对连接实现。 课程1:Android Studio小白安装教程,以及第一个Android项目案例“Hello World”的调试运行 课程2:蓝牙聊天App设计1:Android S

    2024年02月11日
    浏览(56)
  • 【android studio 简单配置多语言国际化app 一行代码实现切换语言】

    新版本的android studio配置多语言其实很简单,不过目前网上找到的几个博客都搞得很复杂,可能是版本比较老的时候出的方案,今天分享一下怎么一行代码切换语言. 1.切换语言你得先有语言对应的文本,推荐插件一键生成.在设置里搜索Androidlocalize,直接安装即可 2.安装好了以后右键

    2024年02月11日
    浏览(52)
  • uniapp 集成 Android Studio 使用原生插件

    前期工作 下载 Android Studio 下载 HbuilderX 对应的 App离线SDK 准备集成 打开选中项目 选中其中的模块文件夹 在该文件夹下的libs目录下添加需要使用的jar包(一般是第三方设备平台提供) 在该文件夹下的srcmainjava下的TestModule.java中写相应的业务实现 需要注意main文件夹下的Andr

    2024年02月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包