Android开发中使用模版功能快速创建MVP模版文件
在android开发中使用MVP模式进行开发最烦的就是要创建model,presenter,view等等一系列文件。这大大的降低了开发效率,那么有没有方法能够解决这个问题呢?这里不得不感谢AS的伟大,他为我们提供了这一类事插件的功能。
在创建Activity的过程中这一张图片大家一定很熟悉
当我们点击Empty Activity时给我们创建了一个带XML布局的Activity,并且帮我们在清单文件中注册了Activity。可能大家之前只用了这个功能,却没有想过为什么他能这样帮我们创建好这些个文件。没错今天要说的这个解决办法就是要依赖这个AS提供的可扩展办法。
我这里用的是Mac系统,Windows系统请自行找到位置
打开应用程序->右击显示包内容........按照上面图片底部的路径找到那个文件夹。是不是很惊喜,哈哈哈哈哈。原来我们在创建Activity是可以选择的模版都在这里。既然找到了根源我们就来看一下他的庐山真面目。
发现一个模版主要就是由上面那几个文件构成。
简单说明一下
globals文件主要是配置一些全局的变量
recipe文件用来将模版文件从模版路径输出到我们想要的路径
template文件就是配置我们新建Activity时的那个新建界面
.png的这张图就是我们的模版预览图片
root 就是我们Activity模版真正实现的地方
这里我贴一下我的MVP的模版代码,大家自行理解吧,应该不难的。
1.globals文件
<?xml version="1.0"?>
<globals>
<global id="hasNoActionBar" type="boolean" value="false" />
<global id="parentActivityClass" value="" />
<global id="excludeMenu" type="boolean" value="true" />
<global id="generateActivityTitle" type="boolean" value="false" />
<global id="activityClass" value="${pageName}Activity" />
<#include "../common/common_globals.xml.ftl" />
</globals>
2.recipe文件
<?xml version="1.0"?>
<#import "root://activities/common/kotlin_macros.ftl" as kt>
<recipe>
<#include "../common/recipe_manifest.xml.ftl" />
<@kt.addAllKotlinDependencies />
<#if generateActivityLayout>
<instantiate from="root/res/layout/simple.xml.ftl"
to="${escapeXmlAttribute(resOut)}/layout/${activityLayoutName}.xml" />
</#if>
<#if generateKotlin>
<instantiate from="root/src/app_package/MVPActivity.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/view/${pageName}Activity.kt" />
<open file="${escapeXmlAttribute(srcOut)}/${pageName}/view/${pageName}Activity.kt" />
<instantiate from="root/src/app_package/MVPContract.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/contract/${pageName}Contract.kt" />
<instantiate from="root/src/app_package/MVPPresenter.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/presenter/${pageName}Presenter.kt" />
<instantiate from="root/src/app_package/MVPModel.kt.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/model/${pageName}Model.kt" />
<#else>
<instantiate from="root/src/app_package/MVPActivity.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/view/${pageName}Activity.java" />
<open file="${escapeXmlAttribute(srcOut)}/${pageName}/view/${pageName}Activity.java" />
<instantiate from="root/src/app_package/MVPContract.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/contract/${pageName}Contract.java" />
<instantiate from="root/src/app_package/MVPPresenter.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/presenter/${pageName}Presenter.java" />
<instantiate from="root/src/app_package/MVPModel.java.ftl"
to="${escapeXmlAttribute(srcOut)}/${pageName}/model/${pageName}Model.java" />
</#if>
</recipe>
3.template文件
<?xml version="1.0"?>
<template
format="5"
revision="5"
name="MVPAutoActivity"
minApi="9"
minBuildApi="14"
description="一键创建MVP架构的所需要的M、P、V文件">
<category value="Activity" />
<formfactor value="Mobile" />
<parameter
id="pageName"
name="Page Name"
type="string"
constraints="unique|nonempty"
default="Main"
help="填写页面名称,如填写Main会自动生成MainActivity,MainPresenter,MainModel文件"
/>
<parameter
id="packageName"
name="Root Package Name"
type="string"
constraints="package"
default="net.ishandian.app"
help="填写项目的包名"
/>
<parameter
id="activityLayoutName"
name="Activtiy Layout Name"
type="string"
constraints="layout|nonempty"
suggest="${activityToLayout(pageName)}"
default="activity_main"
help="填写创建的Activity的布局名称,若布局已经创建就直接填写此包名,没有创建,勾选下面选项"
/>
<parameter
id="generateActivityLayout"
name="Generate Activity Layout"
type="boolean"
default="true"
help="是否生成Activity的布局?若勾选,则用上面的布局作为Activity的布局"
/>
<parameter
id="activityPackageName"
name="Activity Package Name"
type="string"
constraints="package"
suggest="${packageName}.${pageName}.view"
help="Activity 将被输出到此包下,请认真核实此包名是否是你需要输出的目标包名"
/>
<parameter
id="contractPackageName"
name="Contract Package Name"
type="string"
constraints="package"
suggest="${packageName}.${pageName}.contract"
help="Contract 将被输出到此包下"
/>
<parameter
id="presenterPackageName"
name="Presenter Package Name"
type="string"
constraints="package"
suggest="${packageName}.${pageName}.presenter"
help="Presenter 将被输出到此包下"
/>
<parameter
id="modelPackageName"
name="Model Package Name"
type="string"
constraints="package"
suggest="${packageName}.${pageName}.model"
help="Model 将被输出到此包下"
/>
<parameter
id="isLauncher"
name="Launcher Activity"
type="boolean"
default="false"
help="If true, this activity will have a CATEGORY_LAUNCHER intent filter, making it visible in the launcher" />
<parameter
id="backwardsCompatibility"
name="Backwards Compatibility (AppCompat)"
type="boolean"
default="true"
help="If false, this activity base class will be Activity instead of AppCompatActivity" />
<!-- 128x128 thumbnails relative to template.xml -->
<thumbs>
<!-- default thumbnail is required -->
<thumb>template_blank_activity.png</thumb>
</thumbs>
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>
4.MVPActivity.java
package ${activityPackageName};
import ${superClassFqcn};
import android.os.Bundle;
import ${contractPackageName}.${pageName}Contract;
import ${presenterPackageName}.${pageName}Presenter;
import ${packageName}.R;
<#if includeCppSupport!false>
import android.widget.TextView;
</#if>
public class ${pageName}Activity extends ${superClass} implements ${pageName}Contract.View{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.${activityLayoutName});
<#include "../../../../common/jni_code_usage.java.ftl">
}
<#include "../../../../common/jni_code_snippet.java.ftl">
}
5.MVPActivity.kt
package ${activityPackageName}
import ${superClassFqcn}
import android.os.Bundle
import ${contractPackageName}.${pageName}Contract
import ${presenterPackageName}.${pageName}Presenter
import ${packageName}.R
class ${pageName}Activity : ${superClass}(),${pageName}Contract.View {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.${activityLayoutName})
<#include "../../../../common/jni_code_usage.kt.ftl">
}
<#include "../../../../common/jni_code_snippet.kt.ftl">
}
6.MVPContract.java
package ${contractPackageName};
public interface ${pageName}Contract {
//对于经常使用的关于UI的方法可以定义到IView中,如显示隐藏进度条,和显示文字消息
interface View {
}
//Model层定义接口,外部只需关心Model返回的数据,无需关心内部细节,即是否使用缓存
interface Model{
}
}
7.MVPCOntract.kt
package ${contractPackageName}
interface ${pageName}Contract {
//对于经常使用的关于UI的方法可以定义到IView中,如显示隐藏进度条,和显示文字消息
interface View
//Model层定义接口,外部只需关心Model返回的数据,无需关心内部细节,即是否使用缓存
interface Model
}
8.MVPModel.java
package ${modelPackageName};
import ${contractPackageName}.${pageName}Contract;
public class ${pageName}Model implements ${pageName}Contract.Model{
}
9.MVPModel.kt
package ${modelPackageName}
import ${contractPackageName}.${pageName}Contract
class ${pageName}Model constructor() : ${pageName}Contract.Model{
}
10.MVPPresenter.java
package ${presenterPackageName};
import ${contractPackageName}.${pageName}Contract;
public class ${pageName}Presenter {
}
11.MVPPresenter.kt
package ${presenterPackageName}
class ${pageName}Presenter{
}