如果觉得写mvp有点枯燥无味,我们可以做点 cool 的事情:做个 as 插件

help.png

todo-mvp: 基础的MVP架构。

todo-mvp-loaders:基于MVP架构的实现,在获取数据的部分采用了loaders架构。

todo-mvp-databinding: 基于MVP架构的实现,采用了数据绑定组件。

todo-mvp-clean: 基于MVP架构的clean架构的实现。

todo-mvp-dagger2: 基于MVP架构,采用了依赖注入dagger2。

dev-todo-mvp-contentproviders: 基于mvp-loaders架构,使用了ContenPproviders。

dev-todo-mvp-rxjava: 基于MVP架构,对于程序的并发处理和数据层(MVP中的Model)的抽象。

因为对mvp的理解不同,会有很多种方式表达架构,所以插件要极简易读,可扩展性强,所以可以选择:

/**

* 通过模板生成类

* @param var1 文件生成路径

* @param var2 文件名

* @param var3 模板名

* @param var4 是否生产类

* @param var5 模板参数

*/

public abstract PsiClass createClass(@NotNull PsiDirectory var1, @NotNull String var2, @NotNull String var3, boolean var4, @NotNull Map var5) throws IncorrectOperationException;

也就是只要定制不同的模板就可以实现扩展性

直接贴下步骤:

1: idea File - new - Project - IntelliJ Platform Plugin

dir.PNG

plugin.xml 插件配置信息:

com.your.company.unique.plugin.id

Plugin display name here

1.0

YourCompany

Enter short description for your plugin here.

most HTML tags may be used

]]>

Add change notes here.

most HTML tags may be used

]]>

description="Generate MVP" icon="/icons/app_icon.png">

action:

public class MvpGenerator extends AnAction implements MvpHandler.OnGenerateListener {

private AnActionEvent actionEvent;

private MvpHandler mvpHandler;

private Map map = new HashMap<>();

@Override

public void actionPerformed(AnActionEvent anActionEvent) {

this.actionEvent = anActionEvent;

mvpHandler = new MvpHandler();

mvpHandler.setTitle("输入名称-生成MVP相关类");

mvpHandler.setOnGenerateListener(this);

mvpHandler.pack();

//设置对话框跟随当前windows窗口

mvpHandler.setLocationRelativeTo(WindowManager.getInstance().getFrame(anActionEvent.getProject()));

mvpHandler.setVisible(true);

}

@Override

public void onGenerate(String text) {

JavaDirectoryService directoryService = JavaDirectoryService.getInstance();

//当前工程

Project project = actionEvent.getProject();

map.put("NAME", text);

map.put("PACKAGE_NAME", Util.getPackageName(project));

//鼠标右键所选择的路径

IdeView ideView = actionEvent.getRequiredData(LangDataKeys.IDE_VIEW);

PsiDirectory directory = ideView.getOrChooseDirectory();

assert directory != null;

if (directory.getName().contains("contract") && directory.findFile(text + "Contract.java") == null) {

directoryService.createClass(directory, text + "Contract", "GenerateContractFile", true, map);

}

if (directory.getName().contains("model") && directory.findFile(text + "Model.java") == null) {

directoryService.createClass(directory, text + "Model", "GenerateModelFile", true, map);

}

if (directory.getName().contains("presenter") && directory.findFile(text + "Presenter.java") == null) {

directoryService.createClass(directory, text + "Presenter", "GeneratePresenterFile", true, map);

}

}

@Override

public void onCancel() {

mvpHandler.setVisible(false);

}

}

dialog: (action下,右键,new dialog)

public class MvpHandler extends JDialog {

private JPanel contentPane;

private JButton buttonOK;

private JButton buttonCancel;

private JTextArea textArea1;

private OnGenerateListener listener;

public void setOnGenerateListener(OnGenerateListener listener) {

this.listener = listener;

}

public MvpHandler() {

setContentPane(contentPane);

setModal(true);

getRootPane().setDefaultButton(buttonOK);

buttonOK.addActionListener(e -> listener.onGenerate(textArea1.getText().trim()));

buttonCancel.addActionListener(e -> listener.onCancel());

// call onCancel() when cross is clicked

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

listener.onCancel();

}

});

// call onCancel() on ESCAPE

contentPane.registerKeyboardAction(e -> listener.onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

}

public interface OnGenerateListener{

void onGenerate(String text);

void onCancel();

}

}

MvpHandler.form 拖动控件

dialog.PNG

Util:

public class Util {

/**

* AndroidManifest.xml 获取 app 包名

* @return

*/

public static String getPackageName(Project project) {

String package_name = "";

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder db = dbf.newDocumentBuilder();

Document doc = db.parse(project.getBasePath() + "/app/src/main/AndroidManifest.xml");

NodeList nodeList = doc.getElementsByTagName("manifest");

for (int i = 0; i < nodeList.getLength(); i++) {

Node node = nodeList.item(i);

Element element = (Element) node;

package_name = element.getAttribute("package");

}

} catch (Exception e) {

e.printStackTrace();

}

return package_name;

}

}

2: 定制模板:按需求定制

new - file - xxx.java.ft

GenerateContractFile.java.ft

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")

package ${PACKAGE_NAME};

#end

import base.IBaseModel;

import base.IBaseView;

import base.IPresenter;

public interface ${NAME}Contract{

interface I${NAME}View extends IBaseView{

}

interface I${NAME}Model extends IBaseModel{

}

interface I${NAME}Presenter extends IPresenter{

}

}

GenerateModelFile.java.ft

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end

import ${PACKAGE_NAME}.contract.${NAME}Contract;

import base.IBaseModel;

public class ${NAME}Model implements ${NAME}Contract.I${NAME}Model{

public static IBaseModel newInstance(){

return new ${NAME}Model();

}

}

GeneratePresenterFile.java.ft

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")

package ${PACKAGE_NAME}

;#end

import ${PACKAGE_NAME}.contract.${NAME}Contract;

import ${PACKAGE_NAME}.model.${NAME}Model;

import base.BasePresenter;

public class ${NAME}Presenter extends BasePresenter implements ${NAME}Contract.I${NAME}Presenter{

@Override

public ${NAME}Contract.I${NAME}Model bindModel(){

return (${NAME}Contract.I${NAME}Model)${NAME}Model.newInstance();

}

}

MVP:

BasePresenter:

public abstract class BasePresenter implements IPresenter {

protected T mView;

protected M mModel;

protected CompositeDisposable mDisposable;

public BasePresenter() {

this.mModel = bindModel();

mDisposable = new CompositeDisposable();

}

public boolean isViewAttached() {

return mView != null;

}

public void checkViewAttached() {

if (!isViewAttached()) throw new RuntimeException("未注册View");

}

@Override

public void onAttach(T t) {

mView = t;

if (mModel == null) {

throw new NullPointerException("model没有绑定 不能使用");

}

}

/**

* return Model

*/

public abstract M bindModel();

@Override

public void onDetach() {

if (!mDisposable.isDisposed())

mDisposable.dispose();

mView = null;

}

}

IBaseModel:

package base;

/**

* Created by haoran on 2018/4/4.

*/

public interface IBaseModel {

}

IBaseView :

package base;

/**

* Created by haoran on 2017/10/30.

*/

public interface IBaseView {

void showLoading();

void hideLoading();

void onError(String message);

}

IPresenter:

package base;

/**

* Created by haoran on 2017/10/30.

*/

public interface IPresenter {

void onAttach(T t);

void onDetach();

}

实现类:(引导页为例)... import 忽略

GuideContract:

public interface GuideContract {

interface IGuideView extends IBaseView{

void showGuideImages(List pictureListBeans);

void showGuideDefaultImage();

}

interface IGuideModel extends IBaseModel {

Observable> getGuideImages();

}

interface IGuidePresenter extends IPresenter {

void getGuideImages();

}

}

GuideModel:

public class GuideModel implements GuideContract.IGuideModel {

public static IBaseModel newInstance() {

return new GuideModel();

}

public Observable> getGuideImages() {

return ApiHelper.get().getGuideImages(new JSONObject());

}

}

GuidePresenter:

public class GuidePresenter extends BasePresenter implements GuideContract.IGuidePresenter {

@Override

public void getGuideImages() {

checkViewAttached();

mDisposable.add(mModel.getGuideImages().subscribe(pictureList -> {

if (pictureList == null || pictureList.size() == 0) {

mView.showGuideDefaultImage();

} else {

mView.showGuideImages(pictureList);

}

}, throwable -> mView.showGuideDefaultImage()));

}

@Override

public GuideContract.IGuideModel bindModel() {

return (GuideContract.IGuideModel) GuideModel.newInstance();

}

}

根据自己实际的mvp实现类定制模板

3: 打包插件,as引入插件,使用插件(插件开发调试忽略)

打包:idea里 build - Prapare Pulgine Module 'xxx' for Developer

项目目录下的jar包

打开as -- setting pulgine import from disk : jar 包目录

重启as

选中目录(含contract , model ,presenter) alt + i(快捷键可在plugine.xml配置)

或 右键 - new - 点击插件图标

输入 名称(XXX)--- 生成 java 类

generate1.PNG

点击ok

generate2.PNG

感谢:)

android filehelper,为AndroidStudio开发mvp插件(MvpHelper)相关推荐

  1. android studio小案例代码,AndroidStudio开发小相册实例

    郑州app开发AndroidStudio开发小相册实例代码如下. 布局代码如下: java代码如下: package cn.xhhkj.xhhkjtest; import android.app.Ac ...

  2. XM7 FOR ANDROID,如何使用Android Studio开发Gradle插件

    缘由 首先说明一下为什么会有这篇文章.前段时间,插件化以及热修复的技术很热,Nuwa热修复的工具NuwaGradle,携程动态加载技术DynamicAPK,还有希望做最轻巧的插件化框架的Small.这 ...

  3. Android Studio开发-高效插件强烈推荐

    Android Studio开发-高效插件强烈推荐 现在Android的开发者基本上都使用Android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行).使用好And ...

  4. android 程序开发的插件化

    本文为 博客园 黑暗伯爵 原创,转载请注明  http://hangxin1940.cnblogs.com 原文地址:android 程序开发的插件化 模块化方法 之一 框架已经放出: android ...

  5. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  6. Android入门篇(一)了解androidstudio开发软件

    尊重原创,欢迎转载,转载请注明出处! 本人第一次写博客若有瑕疵请见谅. 本人使用的是Androidstudio开发工具,Androidstudio这个软件呢在Androidstudio开源社区就可以下 ...

  7. android studio lua插件,android Studio 配置LUA 开发环境

    android Studio 配置 LUA开发环境 关于Android LUA资料 引诉大牛的原话: Android 调用 Lua /Lua 调用 Android 代码 在Android项目中使用Lu ...

  8. android studio lua插件,[置顶] android Studio 配置LUA 开发环境

    android Studio 配置 LUA 开发环境 关于Android LUA资料 android如何调用lua? Android lua 教程 Lua官网 lua语言解释 Lua 5.1 参考手册 ...

  9. Android开发桌面插件

    前提:公司应用需要开发插件,奈何我实在没有块的开发经验,查阅了一些资料,花了几天时间,完成了插件的开发. 开发桌面插件需要了解AppWidgetProvider,RemoteViewsService, ...

最新文章

  1. iOS应用间相互跳转
  2. 怎么样条件需要做屏蔽机房,屏蔽机房建设标准是什么?
  3. 用qmlscene进行原型制作
  4. TCP的几个状态(SYN/FIN/ACK/PSH/RST)
  5. C/C++ OpenCV直方图均衡化
  6. 什么情况下使用 if()后面的else可以省略不写
  7. VEGAS不等双11,提前嗨购!助你成为视频大神!
  8. 各种Python简单功能代码
  9. make_heap(), pop_heap(), push_heap()用法
  10. centos 7 安装pip
  11. wm java 载入jad错误_jad文件的错误代码,分享
  12. 人机交互课后习题——感知和认知基础
  13. 大数据的75个名词解释
  14. 8产权界定_保护与限制
  15. android 辅助功能(无障碍) AccessibilityService 实战入门详解
  16. teamspeak语音服务器价格,语音聊天社交很热门,带你搭建自己的语音聊天服务器...
  17. webrtc 支持h264 思路
  18. 基于人脸识别的课堂考勤系统 tkinter+openpyxl+face_recognition
  19. 区块链入门教程(4)--搭建单机四节点FISCO BCOS联盟链
  20. wordpress搜索引擎蜘蛛统计插件SEO

热门文章

  1. LwIP应用开发笔记之十:LwIP带操作系统基本移植
  2. 亚马逊S3文件存储的可视化
  3. BigDecimal的个人总结
  4. delphi gui编辑工具源码_Python 快速构建一个简单的 GUI 应用
  5. linux 安装mysql8_MySQL 8.0与MariaDB 10.4,谁更易于填坑补锅?
  6. 转 安卓解决 IDEA 下 struts.xml 中 extends=“struts-default“ 报红的问题
  7. 如何计算实际物理地址?
  8. html中如何让图片交错,HTML5/Canvas 光圈交错幻觉
  9. android手机可以设置屏幕锁定,安卓手机屏幕锁设置方法(九个点图案)
  10. .net 启动mysql数据库连接_[ASP.net教程]mysql数据库连接方式(.net)