美文网首页
intellij-platform-plugin-templat

intellij-platform-plugin-templat

作者: 紫鹰 | 来源:发表于2023-03-22 17:25 被阅读0次

    开发过程中会有大量的模板方法,诸如,生成一个Fragment的时候,需要同时生成一个ViewModel以及一个fragment_layout。同时,在这三个文件内部会生成一些模板方法。这里介绍的intellij-platform-plugin-template就是通过自定义插件的方式,一键批量生成模板方法。
    这里记录一下使用步骤,方便以后查阅

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

    自定义模板插件过程

    1.打开模板地址

    https://github.com/JetBrains/intellij-platform-plugin-template

    2.登录Github,然后点击绿色Use this template按钮。选择Create a new repository,创建自己的仓库。

    3.将模板仓库clone到本地,用AndroidStudio打开

    4.打开android studio目录,找到wizard-template.jar文件

    文件位置为:AS目录\plugins\android\lib。

    5.将wizard-template.jar复制到模板工程的lib文件夹下

    6.修改build.gradle.kts配置依赖,引入wizard-template.jar

      dependencies {
         compileOnly(files("lib/wizard-template.jar"))
      }
    

    7.修改MyProjectManagerListener文件

    package com.github.vhawkmi.sk.listeners
    
    import com.intellij.openapi.components.service
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.project.ProjectManagerListener
    import com.github.vhawkmi.sk.services.MyProjectService
    
    internal class MyProjectManagerListener : ProjectManagerListener {
    
        override fun projectOpened(project: Project) {
             projectInstance = project
            project.getService(MyProjectService::class.java)
       //        project.service<MyProjectService>()
    
       //        System.getenv("CI")
       //            ?: TODO("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.")
        }
    
        override fun projectClosing(project: Project) {
            projectInstance = null
            super.projectClosing(project)
        }
    
        companion object {
            var projectInstance : Project ?= null
        }
    
    }
    

    8.注释MyApplicationService中的TODO

    package com.github.vhawkmi.sk.services
    
    import com.github.vhawkmi.sk.MyBundle
    
    class MyApplicationService {
    
        init {
            println(MyBundle.message("applicationService"))
    
    //        System.getenv("CI")
    //            ?: TODO("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.")
        }
    }
    

    9.注释MyProjectService中的TODO

    package com.github.vhawkmi.sk.services
    
    import com.intellij.openapi.project.Project
    import com.github.vhawkmi.sk.MyBundle
    
    class MyProjectService(project: Project) {
    
        init {
            println(MyBundle.message("projectService", project.name))
    
    //        System.getenv("CI")
    //            ?: TODO("Don't forget to remove all non-needed sample code files with their corresponding registration entries in `plugin.xml`.")
        }
    
        /**
         * Chosen by fair dice roll, guaranteed to be random.
         */
        fun getRandomNumber() = 4
    }
    

    10.修改gradle.properties版本号与插件平台

    pluginVersion = 0.0.2
    platformPlugins =  java, com.intellij.java, org.jetbrains.android, android, org.jetbrains.kotlin
    

    11.修改plugin.xml

    <!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
    <idea-plugin>
        <id>com.github.vhawkmi.sk</id>
        <name>IntelliJ Platform Plugin sk</name>
        <vendor>vhawkmi</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.github.vhawkmi.sk.services.MyApplicationService" />
            <projectService serviceImplementation="com.github.vhawkmi.sk.services.MyProjectService" />
    </extensions>
    
        <applicationListeners>
            <listener class="com.github.vhawkmi.sk.listeners.MyProjectManagerListener" topic="com.intellij.openapi.project.ProjectManagerListener" />
        </applicationListeners>
    
    </idea-plugin>
    

    接下来就是开发插件的过程了

    12.创建Provider

    在kotlin目录下创建开发包,名字自己起,比如generator
    创建文件夹generator/template

    package com.github.vhawkmi.sk.generator

    import com.android.tools.idea.wizard.template.Template
    import com.android.tools.idea.wizard.template.WizardTemplateProvider

    /**

    • @ProjectName: sk

    • @Description: java类作用描述
      */
      class PluginGeneratorProvider : WizardTemplateProvider() {

      override fun getTemplates(): List<Template> = listOf(

      )
      }

    13.在plugin.xml中注册改provider

       <!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
     <idea-plugin>
         
        <其他配置不再赘述>
    
        <extensions defaultExtensionNs="com.android.tools.idea.wizard.template">
            <wizardTemplateProvider implementation="com.github.vhawkmi.sk.generator.PluginGeneratorProvider" />
        </extensions>
    
    </idea-plugin>
    

    14.创建文件模板

    在文件夹虾创建文件FragmentTemplate.kt

    package com.github.vhawkmi.sk.generator.template.fragment
    
    
    
    fun simpleFragmentTemplate(packageName : String,modelName : String,viewName : String,desc : String) = """
    package ${packageName}.ui
    
    import android.os.Bundle
    import androidx.fragment.app.viewModels
    import androidx.recyclerview.widget.LinearLayoutManager
    import com.qiuku8.android.R
    import com.qiuku8.android.databinding.Fragment${modelName}Binding
    import ${packageName}.viewmodel.${modelName}ViewModel
    import com.qiuku8.android.ui.base.BaseBindingFragment
    
    /**
     *
     * @Description:  ${desc}  
     */
    class ${modelName}Fragment : BaseBindingFragment<Fragment${modelName}Binding>() {
    
        private val viewModel: ${modelName}ViewModel by viewModels()
        private var mAdapter = ${modelName}Adapter()
        override fun getLayout(): Int {
            return R.layout.${viewName}
        }
    
        override fun initDatas(savedInstanceState: Bundle?) {
            lifecycle.addObserver(viewModel)
            addObserver()
        }
    
        private fun addObserver() {
            viewModel.uiStatusLiveData.observe(this){uiStatus ->
                uiStatus.loadingStatus?.let { loadingStatus ->
                    binding.layoutLoading.status = loadingStatus
                }
                uiStatus.noMoreData?.let { noMore ->
                    binding.layoutRefresh.setNoMoreData(noMore)
                }
                uiStatus.isRefreshing?.let {
                    binding.layoutRefresh.finishRefresh()
                    binding.layoutRefresh.finishLoadMore()
                }
               // todo 特征处理
            }
        }
    
        override fun initViews() {
            binding.layoutLoading.setOnReloadListener {
                // todo reload
            }
    
            binding.layoutRefresh.setEnableRefresh(true)
            binding.layoutRefresh.setEnableLoadMore(true)
            binding.layoutRefresh.setOnRefreshListener {
                // todo refresh
            }
    
            binding.recycleContent.let {
                it.layoutManager = LinearLayoutManager(requireActivity())
                it.adapter = mAdapter
            }
        }
    
        override fun initEvents() {
    
        }
    }
    

    """

    LayoutFragmentTemplate.kt文件

    package com.github.vhawkmi.sk.generator.template.layout
    
    
    fun simpleLayoutTemp(desc : String) = """
    <?xml version="1.0" encoding="utf-8"?>
    <layout>
    
        <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
            <xxxx需要的布局文件,这里不举例子了>
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>
    

    """

    这些文件,按需生成即可

    15.创建写入类SimpleFragmentRecipe.kt

    package com.github.vhawkmi.sk.generator
    
    import com.android.tools.idea.wizard.template.Language
    import com.android.tools.idea.wizard.template.ModuleTemplateData
    import com.android.tools.idea.wizard.template.RecipeExecutor
    import com.github.vhawkmi.sk.generator.template.bean.simpleUiStatusTemplate
    import com.github.vhawkmi.sk.generator.template.fragment.simpleFragmentTemplate
    import com.github.vhawkmi.sk.generator.template.layout.simpleLayoutTemp
    import com.github.vhawkmi.sk.generator.viewmodel.simpleViewModelTemplate
    
    fun RecipeExecutor.simpleFragmentRecipe(
    moduleData: ModuleTemplateData,
    packageName: String,
    modelName: String,
    layoutName: String,
    desc: String,
    language: Language
    ) {
        val (projectData, srcOut, resOut) = moduleData
        val ktOrJavaExt = language.extension
    
        if (language == Language.Kotlin) {
            // 生成 Fragment
            save(
                simpleFragmentTemplate(packageName = packageName, modelName = modelName, viewName = layoutName, desc = desc),
                srcOut.resolve("ui/${modelName}Fragment.${ktOrJavaExt}")
            )
            // 生成 ViewModel
            save(simpleViewModelTemplate(packageName, modelName, desc), srcOut.resolve("viewmodel/${modelName}ViewModel.${ktOrJavaExt}"))
            // 生成UIStatus
            save(simpleUiStatusTemplate(packageName, modelName, desc), srcOut.resolve("bean/${modelName}UiStatus.${ktOrJavaExt}"))
    
            //生成 fragment_layout
            save(simpleLayoutTemp(desc), resOut.resolve("layout/${layoutName}.xml"))
        }
    }
    

    16.创建生成器SimpleFragmentGenerator.kt

    package com.github.vhawkmi.sk.generator
    
    import com.android.tools.idea.wizard.template.*
    import com.android.tools.idea.wizard.template.impl.activities.common.MIN_API
    import com.github.vhawkmi.sk.defaultPackageNameParameter
    
    val simpleFragmentGenerator
        get() = template {
            name = "mmvm fragment"
            description = "生成mmvm框架的Fragment和layout以及viewmodel"
            minApi = MIN_API
            category = Category.Fragment
            formFactor = FormFactor.Mobile
            screens = listOf(WizardUiContext.ActivityGallery, WizardUiContext.MenuEntry, WizardUiContext.NewProject, WizardUiContext.NewModule)
    
    
            val modelName = stringParameter {
                name = "Model Name"
                default = "XxxModel"
                help = "请输入model的名字"
                constraints = listOf(Constraint.NONEMPTY)
    
            }
    
            val layoutName = stringParameter {
                name = "layout name"
                default = "fragment_xxx"
                help = "请输入布局的名字"
                constraints = listOf(Constraint.LAYOUT, Constraint.UNIQUE, Constraint.NONEMPTY)
                suggest = { "fragment_${camelCaseToUnderlines(modelName.value)}" }
            }
    
    
            val descName = stringParameter {
                name = "Desc Name"
                default = "描述信息"
                help = "请输入描述"
                constraints = listOf(Constraint.NONEMPTY)
    
           }
    
            val language = enumParameter<Language> {
            name = "Source Language"
            help = "请选择语言"
            default = Language.Kotlin
           }
    
            val packageName = defaultPackageNameParameter
    
            widgets(
                TextFieldWidget(modelName),
                TextFieldWidget(layoutName),
                TextFieldWidget(descName),
                PackageNameWidget(packageName),
                EnumWidget(language)
            )
    
            recipe = {
                simpleFragmentRecipe(
                    moduleData = it as ModuleTemplateData,
                    packageName = packageName.value,
                    modelName = modelName.value,
                    layoutName = layoutName.value,
                    desc = descName.value,
                    language = language.value
                )
            }
        }
    

    17.Provider中添加代码生成器

    package com.github.vhawkmi.sk.generator
    
    import com.android.tools.idea.wizard.template.Template
    import com.android.tools.idea.wizard.template.WizardTemplateProvider
    
    class PluginGeneratorProvider : WizardTemplateProvider() {
    
        override fun getTemplates(): List<Template> = listOf(
            simpleFragmentGenerator,
       )
    

    }

    18.打包

    设置RunConfig为Run Plugin,运行 run plugin

    19.将生成的jar包作为一个插件安装到AndroidStudio中

    20.在项目中使用

    相关文章

      网友评论

          本文标题:intellij-platform-plugin-templat

          本文链接:https://www.haomeiwen.com/subject/tyqbrdtx.html