android filehelper,为AndroidStudio开发mvp插件(MvpHelper)
如果觉得写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)相关推荐
- android studio小案例代码,AndroidStudio开发小相册实例
郑州app开发AndroidStudio开发小相册实例代码如下. 布局代码如下: java代码如下: package cn.xhhkj.xhhkjtest; import android.app.Ac ...
- XM7 FOR ANDROID,如何使用Android Studio开发Gradle插件
缘由 首先说明一下为什么会有这篇文章.前段时间,插件化以及热修复的技术很热,Nuwa热修复的工具NuwaGradle,携程动态加载技术DynamicAPK,还有希望做最轻巧的插件化框架的Small.这 ...
- Android Studio开发-高效插件强烈推荐
Android Studio开发-高效插件强烈推荐 现在Android的开发者基本上都使用Android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行).使用好And ...
- android 程序开发的插件化
本文为 博客园 黑暗伯爵 原创,转载请注明 http://hangxin1940.cnblogs.com 原文地址:android 程序开发的插件化 模块化方法 之一 框架已经放出: android ...
- android黑科技系列——微信抢红包插件原理解析和开发实现
一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...
- Android入门篇(一)了解androidstudio开发软件
尊重原创,欢迎转载,转载请注明出处! 本人第一次写博客若有瑕疵请见谅. 本人使用的是Androidstudio开发工具,Androidstudio这个软件呢在Androidstudio开源社区就可以下 ...
- android studio lua插件,android Studio 配置LUA 开发环境
android Studio 配置 LUA开发环境 关于Android LUA资料 引诉大牛的原话: Android 调用 Lua /Lua 调用 Android 代码 在Android项目中使用Lu ...
- android studio lua插件,[置顶] android Studio 配置LUA 开发环境
android Studio 配置 LUA 开发环境 关于Android LUA资料 android如何调用lua? Android lua 教程 Lua官网 lua语言解释 Lua 5.1 参考手册 ...
- Android开发桌面插件
前提:公司应用需要开发插件,奈何我实在没有块的开发经验,查阅了一些资料,花了几天时间,完成了插件的开发. 开发桌面插件需要了解AppWidgetProvider,RemoteViewsService, ...
最新文章
- iOS应用间相互跳转
- 怎么样条件需要做屏蔽机房,屏蔽机房建设标准是什么?
- 用qmlscene进行原型制作
- TCP的几个状态(SYN/FIN/ACK/PSH/RST)
- C/C++ OpenCV直方图均衡化
- 什么情况下使用 if()后面的else可以省略不写
- VEGAS不等双11,提前嗨购!助你成为视频大神!
- 各种Python简单功能代码
- make_heap(), pop_heap(), push_heap()用法
- centos 7 安装pip
- wm java 载入jad错误_jad文件的错误代码,分享
- 人机交互课后习题——感知和认知基础
- 大数据的75个名词解释
- 8产权界定_保护与限制
- android 辅助功能(无障碍) AccessibilityService 实战入门详解
- teamspeak语音服务器价格,语音聊天社交很热门,带你搭建自己的语音聊天服务器...
- webrtc 支持h264 思路
- 基于人脸识别的课堂考勤系统 tkinter+openpyxl+face_recognition
- 区块链入门教程(4)--搭建单机四节点FISCO BCOS联盟链
- wordpress搜索引擎蜘蛛统计插件SEO
热门文章
- LwIP应用开发笔记之十:LwIP带操作系统基本移植
- 亚马逊S3文件存储的可视化
- BigDecimal的个人总结
- delphi gui编辑工具源码_Python 快速构建一个简单的 GUI 应用
- linux 安装mysql8_MySQL 8.0与MariaDB 10.4,谁更易于填坑补锅?
- 转 安卓解决 IDEA 下 struts.xml 中 extends=“struts-default“ 报红的问题
- 如何计算实际物理地址?
- html中如何让图片交错,HTML5/Canvas 光圈交错幻觉
- android手机可以设置屏幕锁定,安卓手机屏幕锁设置方法(九个点图案)
- .net 启动mysql数据库连接_[ASP.net教程]mysql数据库连接方式(.net)