前言
Android开发中经常需要创建Activity。一般情况下,咱们都是"New"->Java Class/Activity。但是Android Studio自带的Activity模板都比较简单,未必符合我们所需的模板样式。例如在MVP框架下,需创建Activity、Present、Contract、Model等文件,并关联关系,初始化、author、统一的网络请求写法。所以我们需要自定义模板,帮我们省去这一系列重复操作。
举个栗子,创建自定义MVP模板(本文较长,赶时间的小伙伴可以到底部下载源码)
图解1 配置创建信息
MVP Name为红框标记部分统一命名(Activity、Layout、Contract、Model、Present)。由Generate MVP File选择框决定是否在生成activity的同时生成Contract、Model和Presenter等Java类。
图解2 文件结构
点击Finish完成创建后,可以看到自动生成的文件(如下图)
这里我们主要看自动生成的HomePageActivity。其他仨请看开头Gif,这里就不一一截图了
以上内容均为自动生成,使用过MVP的小伙伴是不是很熟悉?是不是很方便?妈妈再也不用担心我的CV大法导致代码区域乱七八糟了。
PS:每个项目MVP有或多或少差异,大家可以根据项目实际编写合适的模板。
附上Activity分区注释
/*-----------------------静态Activity启动方法区-------------------*/
/*-----------------------常量声明区-------------------------------*/
/*-----------------------UI控件成员变量声明区---------------------*/
/*-----------------------普通成员变量声明区-----------------------*/
/*-----------------------初始化相关方法区-------------------------*/
/*-----------------------生命周期回调方法区(除onCreate()方法外)- */
/*-----------------------事件响应方法区---------------------------*/
/*-----------------------重载的逻辑方法区-------------------------*/
/*-----------------------普通逻辑方法区---------------------------*/
/*-----------------------内部接口声明区---------------------------*/
/*-----------------------内部类声明区-----------------------------*/
如何自定义模板
1.熟悉安卓模板
在Android Studio的安装目录下 \plugins\android\lib\templates\activities
(同Mac)保存着系统自带的activity模板和我们自定义的模板
在编写自定义模板前,需要熟悉下模板的结构和组成,这里我们从最简单的模板EmptyActivity入手
src:代码文件,生成对应的文件模板
globals.xml.ftl:Java类库,主要用于提供参数。可存储全局变量以供其他模板文件统一引用
recipe.xml.ftl:用于组合生成我们实际需要的代码文件和布局文件等。
template.xml:相当于Android中的布局文件,用于图形化提供参数,布局等。
template_blank_activity.png:模板照片
自定义模板通常都是复制已有,然后再修改修改
globals.xml.ftl
存储全局变量。每一个变量定义,由id 唯一标识,type 类型,value 实际值组成
recipe.xml.ftl
即便不懂freemarker引擎也不影响,也能依样画葫芦,这里就简单讲下用到的标签及含义:
instantiate
将 ftl->java文件,中间会通过一个步骤,将ftl中的变量都换成对应的值,完整的流程是 ftl->freemarker process -> java 。open
用于转换完成时在项目中对应的包下生成对应文件,例如Activityif
if指令,这里if判断是否生成layout文件- <#if >
<#elseif >
<#else >
</#if >
- <#if >
template.xml
对应用户输入的模板界面,
<parameter>
获取用户输入参数
id
唯一标识,通过该属性,获取输入值,也可用于其他文件查找引用name
标签名称,类似label展示给用户看type
输入值类型constraints
填写值的约束suggest
建议值,例如填写Activity Name,给出一个建议值help
底部提示语言,对应图形化界面操作
几个文件的整体的关系类似下图:
图片来源:http://www.slideshare.net/murphonic/custom-android-code-templates-15537501
2.定义MVPActivity模板
了解完以上简单介绍,基本足够我们写自(zhào)定(yàng)义(huà)模(hú)板(lū)
2.1创建MVPActivity文件夹
一般都是复制现有的(例如EmptyActivity,或者文章末尾的源码),再改改。
添加MVP所对应文件
2.2编写MVP相关文件
activity_mvp.xml.ftl
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}">
</RelativeLayout>
IContract.java.ftl
package ${
packageName};
import com.xx.mvp.base.BaseModel;
import com.xx.mvp.base.BasePresenter;
import com.xx.mvp.base.BaseView;
import rx.Observable;
<#assign aDateTime = .now>
/**
* Model: {@link ${modelName}} View:{@link ${activityClass}} Presenter:{@link ${presenterName}}
* @Author: ${author}
* @Description:
* @Date: Create in ${aDateTime}
* @Modified By:
*/
public interface ${
contractName} {
interface Model extends BaseModel {
/**
* 更新数据
*
* @return
*/
Observable<Object> update();
}
interface View extends BaseView {
}
interface Presenter extends BasePresenter<Model, View> {
/**
* 更新数据
*/
void update();
}
}
Model.java.ftl
package ${
packageName};
import com.xx.bean.base.BaseResult;
import com.xx.http.rx.TransformUtils;
import com.xx.mvp.base.BaseModelImpl;
import retrofit2.http.POST;
import rx.Observable;
<#assign aDateTime = .now>
/**
* Present: {@link ${presenterName}}
* @Author: ${author}
* @Description:
* @Date: Create in ${aDateTime}
* @Modified By:
*/
public class ${
modelName} extends BaseModelImpl<${
modelName}.Service> implements ${
contractName}.Model {
public ${
modelName}() {
super(${
modelName}.Service.class);}
@Override
public Observable<Object> update() {
return getRequestService()
.update()
.compose(TransformUtils.defaultSchedulers());
}
public interface Service {
/**
* 更新数据
*
* @return
*/
@POST("pos-web/updateAllData")
Observable<BaseResult<Object>> update();
}
}
MVPActivity.java.ftl
package ${
packageName};
import ${
superClassFqcn};
import android.os.Bundle;
<#if includeCppSupport!false>
import android.widget.TextView;
</#if>
<#assign aDateTime = .now>
/**
<#if generateMVP>
* Model: {@link ${modelName}} Presenter:{@link ${presenterName}}
</#if>
* @Author: ${author}
* @Description:
* @Date: Create in ${aDateTime}
* @Modified By:
*/
<#if generateMVP>
public class ${
activityClass} extends BaseActivity<${
contractName}.Model, ${
contractName}.View, ${
contractName}.Presenter> implements ${
contractName}.View