MVC,MVP,MVPVM(二)提升效率之Templates

文章目录

1.MVC,MVP,MVPVM(一)实践之路
2.MVC,MVP,MVPVM(二)提升效率之Templates

遗留问题

《MVC,MVP,MVPVM(一)实践之路》中讲到如何从MVC到MVPVM的转变,将各个模块分离,职责划清。不过有个缺点,就是类爆炸,为什么代码写着写着就MVC了,就是因为一个Activity搞定,写着爽。但是,如果要实现解耦,就一定意味着会有很多不同的职能类。如果采用mvp,或mvpvm的实现方式,每次在新建一个页面就需要差不多10+个文件,虽然逻辑简单,不过全都手动创建的话,是不是觉得还是MVC好。

so many class.png
so many class.png
解决方案

套用定义好的代码Templates,自动生成各个职能类。

mvpvm_templates.gif
mvpvm_templates.gif

模版地址:
https://github.com/listen2code/Test_MVPVM/tree/master/doc/MvpvmComponent

使用介绍

1.将写好的templates拷贝到本地
Android Studio.app/Contents/plugins/android/lib/templates/activities/
2.重启AndroidStudio,右键项目->New->Activity->MvpvmComponent
3.在打开的编辑页面输入ActivityName和layoutName,包名为"com.listen.test_mvpvm"


templates_input.png
templates_input.png

根据Templates自动生成的类


classes_generate.png
classes_generate.png
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable name="data" type="com.listen.test_mvpvm.model.viewmodel.ITestMvpvmViewModel"/>
        <variable name="presenter" type="com.listen.test_mvpvm.presenter.ITestMvpvmPresenter"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="@{data.text}"/>

        <Button
            android:id="@+id/btn_test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_test"
            android:onClick="@{presenter.onClickAction}"
            android:text="@{data.buttonText}"/>

    </LinearLayout>
</layout>
public class TestMvpvmActivity extends AppCompatActivity implements ITestMvpvmView {

    private ActivityTestMvpvmBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_test_mvpvm);
        mBinding.setPresenter(new TestMvpvmPresenter(this));
    }

    @Override
    public void updateView(ITestMvpvmViewModel viewModel) {
        mBinding.setData(viewModel);
    }
}
public class TestMvpvmPresenter implements OnTestMvpvmListener, ITestMvpvmPresenter {

    private ITestMvpvmView mITestMvpvmView;
    private ITestMvpvmRepository mTestMvpvmRepository;

    public TestMvpvmPresenter(ITestMvpvmView iTestMvpvmView) {
        this.mITestMvpvmView = iTestMvpvmView;
        this.mTestMvpvmRepository = new TestMvpvmRepositoryImpl(this);
    }

    public void onClickAction(View v) {
        mTestMvpvmRepository.method("");
    }

    public void onTestMvpvmLoadSuccess(TestMvpvmModel data) {
        mITestMvpvmView.updateView(new TestMvpvmViewModel(data));
    }

    public void onTestMvpvmLoadFail(String errorMessage) {
    }
}
public class TestMvpvmRepositoryImpl implements ITestMvpvmRepository {

    private OnTestMvpvmListener mOnTestMvpvmListener;

    public TestMvpvmRepositoryImpl(OnTestMvpvmListener onTestMvpvmListener) {
        this.mOnTestMvpvmListener = onTestMvpvmListener;
    }

    public void method(String param) {
        new HttpTask() {
            @Override
            public void onRequestSuccess(TestMvpvmModel model) {
                mOnTestMvpvmListener.onTestMvpvmLoadSuccess(model);
            }
        }.path("http://xxxx/getMydeposit").execute();
    }
}
Templates介绍

Templates由3个xml描述文件,和一堆.flt文件组成。

template_1.png
template_1.png

template2.png
template2.png

globals.xml.ftl:主要用于定义一些全局变量,正常如果要自定义模版的话,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" />
    <#include "../common/common_globals.xml.ftl" />
</globals>

template.xml:我们在新建模版时,会有个填写信息的页面,template文件主要用于描述该页面上的元素信息。


templates_input.png
templates_input.png
<template
    format="5"
    revision="8"
    name="MvpvmComponent"
    minApi="7"
    minBuildApi="14"
    description="Creates mvpvm components">

    <category value="Activity" />
    <formfactor value="Mobile" />

    <!-- 上图中第一个"Component Name"输入框的描述 -->
    <parameter
        id="activityClass"// 唯一性ID,后面会在.flt中引用
        name="Component Name"// 输入框前的描述提示语
        type="string"// 输入值类型
        constraints="class|unique|nonempty"
        suggest="${layoutToActivity(activityLayoutName)}"// 输入约束
        default="Mvpvm"// 默认输入值
        help="The name of the component" />//底部提示语

    <parameter
        id="activityLayoutName"
        name="Layout Name"
        type="string"
        constraints="layout|unique|nonempty"
        suggest="${activityToLayout(activityClass)}"
        default="activity_mvp"
        help="The name of the layout" />

    <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="packageName"
        name="Package name"
        type="string"
        constraints="package"
        suggest="com.listen.test_mvpvm"
        default="com.listen.test_mvpvm" />

    <globals file="globals.xml.ftl" />
    <execute file="recipe.xml.ftl" />

</template>

recipe.xml.flt:将root目录下的.flt文件解析成.java文件,并打开。

<?xml version="1.0"?>
<recipe>

    <!-- 处理模版 -->
    <instantiate from="root/src/app_package/MvpActivity.java.ftl"
        to="${escapeXmlAttribute(srcOut)}/view/${activityClass}Activity.java" />

    <!-- 打开xin -->
    <open file="${escapeXmlAttribute(srcOut)}/view/${activityClass}Activity.java" />

</recipe>

MvpActivity.java.flt文件示例,引用template中的
"@{activityClass}","${activityLayoutName}",就是在输入页面填写的ActivityName,和layoutName。将"@{}"解析后生成完整的Activity.java。其实Templates的原理,就是将你需要生成的java文件的公用部分抽取出来,用"@{}"占位符,替代会变化的keyWord,写成一个个.flt模版文件,同时在输入面板中将keyWord输入,并通过template.xml,recipe.xml等描述文件,最终合成我们需要的java文件。

public class ${activityClass}Activity extends AppCompatActivity implements I${activityClass}View {

    private Activity${activityClass}Binding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.${activityLayoutName});
        mBinding.setPresenter(new ${activityClass}Presenter(this));
    }

    @Override
    public void updateView(I${activityClass}ViewModel viewModel) {
        mBinding.setData(viewModel);
    }
}

通过定义Templates,在每次新建一个页面时节省了大量重复的类创建工作,我们可以运用Templates定义各种页面模版,可以大幅度的提升开发效率。在日常工作中,应该尽可能减少一些纯体力的,重复的代码拷贝。不过为优化,为解耦而增加再多类,分再多模块都是值得的。

Templates更详细介绍可以参考鸿洋的文章,这里不做赘述:http://blog.csdn.net/lmj623565791/article/details/51635533

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,353评论 6 344
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • 惺忪之间已子时,朦胧不见窗外光。 触手不见枕边人,顿觉大梦已初醒。 梦里蘧然长相守,实则一人早半生。
    老苍的浮生阅读 232评论 0 0
  • 今天六点钟闹钟准确无误地履行着自己的职责,天还很黑很冷,我心里说再睡会儿,再醒来已是将近七点,我心里开始骂自己,...
    茶话心语阅读 231评论 0 0