在编写android项目中,我们难免会重复的去写一些东西或者写一些浪费时间但又和我们项目逻辑关系不大的代码,所以学会编写模板代码变得很重要,我这里指得模板有两种:
单个文件
-
某个功能
对于第一种情况,如下:
在上面我们仿照系统文件新建了两个模板类,RecycleViewAdapter和Singleton,在我们新建类列表中可以看到。我们得代码是仿照着class文件编写得,class文件内容如下:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME} {
}
PACKAGE_NAME | NAME | File Header.java |
---|---|---|
包名 | 类名 | 头部文件说明 |
头部文件如下:
这里单例实现用静态内部类实现得,因为静态内部类初始化是由java虚拟机管理的,classloder加载,线程安全,下面是这两个类的代码:
singleton.java
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME}{
public static ${NAME} getInstance() {
return ${NAME}Holder.sInstance;
}
private ${NAME}() {
}
private static class ${NAME}Holder {
private static final ${NAME} sInstance = new ${NAME}();
}
}
RecycleViewAdapter.java
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
#parse("File Header.java")
public class ${NAME} extends RecyclerView.Adapter<${NAME}.ViewHolder> {
private Context ctx; private List
最后使用的话就很简单了,在我们第一张图中新建模板上面两个类就是我们新建的模板,直接点击就可以生成我们想要的类了,我们只需要输入相应的类名即可。
第二种情况是针对某个功能,我们可能会新建很多上面的那种类,就是我们新建项目的时候系统提供给我们提供的各种模板,在Android studio中新建activity、fragment时用到。会同时新建相应的布局,注册manifest等等,如下:
上面这个模板本来是MVPArm作者写的,是一个mvp+dagger的架构实现,我这里对里面的部分内容进行了修改,用以适应我自己的demo,整个模板的核心是freemarker,实现思路如下:
freemarker作用是把我们写的.jva.ftl文件生成我们自己需要的.java文件,而我们需要生成的文件名,布局名、包名等内容在初始化界面时输入即可,整个功能是一个单独的包,现在我们来分析一下这个组件的包里面的内容:
如上图,我们需要的所有内容就在MVPTemplate里面,其中最重要的是template.xml,这里面进行我们需要关键字的注册,如包名、类名啥的:
template.xml
template_blank_activity.png
上面大部分属性猜大概都能猜出来什么意思,比较重要的是
package ${ativityPackageName};
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import ${packageName}.R;
import ${componentPackageName}.Dagger${pageName}Component;
import ${moudlePackageName}.${pageName}Module;
import ${contractPackageName}.${pageName}Contract;
import ${presenterPackageName}.${pageName}Presenter;
import javax.inject.Inject;
public class ${pageName}Activity extends AppCompatActivity implements ${pageName}Contract.View {
@Inject
${pageName}Presenter ${pageName}Presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.${activityLayoutName});
Dagger${pageName}Component.builder()
.${extractLetters(pageName[0]?lower_case)}${pageName?substring(1,pageName?length)}Module(new ${pageName}Module(this))
.build()
.inject(this);
${pageName}Presenter.getData();
}
@Override
public void showLoading() {
}
@Override
public void hideLoading() {
}
@Override
public void showMessage(String message) {
}
@Override
public void launchActivity(Intent intent) {
}
@Override
public void killMyself() {
}
@Override
public void showData(String string) {
Log.e("yy", string);
}
}
代码中用${}符号表示EL表达式,目的是为了在代码中能够调用到template中传入的内容,仔细看我们的template.xml文件结尾其实还有两个类,globals.xml.ftl和recipe.xml.ftl,也包含一个生成案例的图片展示thumb字段,globals.xml.ftl中主要是声明一些属性格式:
<#include "../common/common_globals.xml.ftl" />
recipe.xml.ftl文件主要是告诉freemarker文件从什么地方来(from xxx.java.ftl),到什么地方去(to xxx.java),如下:
<#if needActivity>
#if>
<#if needActivity && generateActivityLayout>
#if>
<#if needFragment && generateFragmentLayout>
#if>
<#if needActivity>
#if>
<#if needFragment>
#if>
<#if needContract>
#if>
<#if needPresenter>
#if>
<#if needModel>
#if>
<#if needDagger>
#if>
可以看到,来源就是我们已经编写好的.java.ftl文件,去向是还未命名的.java文件,我改这个东西是复制一份包,直接进行改的,改好后放进去就行了,如果没改好,你是生不成代码的,好好去检查一下包下面的文件。
自定义类和模块模板的内容到这里就基本上结束了,希望对大家的开发有所帮助,最后说一个题外话,第一次转到来,熟悉markdown编辑器的语法花了一些时间,最后下载了一个有界面的markdown编辑器小书匠写的本篇文章。
模板包下载:百度网盘
密码:5lk7
推荐文章
mvp架构之路,从简单到复杂
Markdown编辑器一览,总有一款适合你
一键生成 MVP , Dagger2 相关类