- 。
我为什么选这个呢?因为创意好,实用并且代码简单。
贴一个今天这个插件的最终效果图:
注:效果与ECTranslation基本一致,本文仅用作学习,不造轮子,如果需要使用,直接使用ECTranslation即可。
二、准备工作
首先需要安装IntelliJ IDEA
下载好就可以了~~
然后安装,运行,点击create New Project:
按照上图进行选择,如果没有SDK,则点击New新建一个即可。
然后点击Next,输入项目名称选择位置,就可以点击finish了。
项目的结构如下:
src目录下主要用于存放我们编写的代码。
这样准备工作就结束了~~
三、编码
(1) 关键知识
编码实际上核心的一个类叫做AnAction,可以直接选择NEW->Action,如下图:
然后填写一些相关信息:
需要填写的属性如下:
- ActionID:代表该Action的唯一的ID,一般的格式为:pluginName.ID
- ClassName:类名
- Name:就是最终插件在菜单上的名称
- Description:对这个Action的描述信息
然后往下,选择这个Action即将存在的位置:
我们选择的是EditMenu,右侧选择为first,即EditMenu下的第一个,效果如图:
再往下就是制定快捷键了~~
都填写完成就可以点击OK了。
点击ok之后,可以看到为我们生成了下类:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TranslateAction</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AnAction</span> {</span>
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">actionPerformed</span>(AnActionEvent e) {
<span class="hljs-comment">// TODO: insert action logic here</span>
}
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>
此外我们刚才填写的信息,也在plugin.xml中完成了注册,大家可以进去看一眼,actions的标签中,
当我们点击菜单的时候,就回触发actionPerformed()
方法。
那么这么看,我们在这个方法中只要完成三件事:
- 获得当前选中的单词
- 调用相关API得到单词的意思
- 通过一个类似于PopupWindow来显示
当然,为了尽快的测试,你可以先在里面弹一个对话框,例如如下:
<code class="language-java hljs has-numbering"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">actionPerformed</span>(AnActionEvent event) {
Messages.showMessageDialog(<span class="hljs-string">"Hello World !"</span>, <span class="hljs-string">"Information"</span>, Messages.getInformationIcon());
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>
预期效果是点击Tranlate菜单,或者按快捷键会弹出一个提示对话框。
那么点击Run:
然后它会默认启动一个新的IntelliJ IDEA的界面,你可以随便新建一个项目,进入以后,你会发现Edit下多了一个Translate菜单,点击即可弹出我们设定的对话框:
ok,测试通过就放心了~
- 获得当前选中的单词
- 调用相关API得到单词的意思
- 通过一个类似于PopupWindow来显示
剩下的就是功能性的API了~
(2) 获得当前选中的单词
<code class="language-java hljs has-numbering"> <span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">actionPerformed</span>(AnActionEvent e) {
<span class="hljs-comment">// TODO: insert action logic here</span>
<span class="hljs-keyword">final</span> Editor mEditor = e.getData(PlatformDataKeys.EDITOR);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">null</span> == mEditor) {
<span class="hljs-keyword">return</span>;
}
SelectionModel model = mEditor.getSelectionModel();
<span class="hljs-keyword">final</span> String selectedText = model.getSelectedText();
<span class="hljs-keyword">if</span> (TextUtils.isEmpty(selectedText)) {
<span class="hljs-keyword">return</span>;
}
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul>
是不是觉得API很陌生,恩,我也觉得很陌生,关于API这里介绍其实没什么意义,本文主要目的是让大家对自定义插件有个类helloworld的认识,至于插件里面的代码涉及到的API等到大家需要编写插件的时候,再详细学习就好了,现在就不要浪费精力记忆这些东西了。
上面的代码就是获得选中的文本,通过一个Editor,然后拿到SelectionModel,再拿到selectedText,从字面上还是蛮好理解的。
拿到选中的文本之后,应该就是去查询该单词的意思了,查询呢,ECTranslation用的是youdao的Open SDK,其实也很简单,就是拼接一个url,然后等着解析返回数据就好了。
(3)调用相关API得到单词的意思
- 大家如果想要做单词翻译,可以看下,非常简单。
涉及到的代码:
<code class="language-java hljs has-numbering">String baseUrl = <span class="hljs-string">"http://fanyi.youdao.com/openapi.do?keyfrom=Skykai521&key=977124034&type=data&doctype=json&version=1.1&q="</span>;
HttpUtils.doGetAsyn(baseUrl + selectedText, <span class="hljs-keyword">new</span> HttpUtils.CallBack() {
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onRequestComplete</span>(String result) {
Translation translation = gson.fromJson(result, Translation.class);
showPopupBalloon(mEditor, translation.toString());
}
});</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul>
HttpUtils就不贴了,就是直接开了个线程,通过HttpUrlConnection去访问网络,大家的项目中或者通过搜索引擎,代码一搜一堆。
baseUrl就是有道的url,加上我们选中的单词就是完整的url了,然后通过http访问,callback回调出返回的字符串,这里返回的是json类型的字符串。
我们根据返回的json字符串生成了一个类Translation;
然后通过Gson转化为Translation对象。
ps:拿着上面的baseUrl后面跟一个任何单词,直接访问浏览器就能看到返回的json数据了,这里大家天天写接口,类似的步骤比我肯定还熟悉。
好了,有了返回的数据以后,直接通过一个类似popupWindow展现即可。
(4)通过一个类似于PopupWindow来显示
涉及到的代码:
<code class="language-java hljs has-numbering"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showPopupBalloon</span>(<span class="hljs-keyword">final</span> Editor editor, <span class="hljs-keyword">final</span> String result) {
ApplicationManager.getApplication().invokeLater(<span class="hljs-keyword">new</span> Runnable() {
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
JBPopupFactory factory = JBPopupFactory.getInstance();
factory.createHtmlTextBalloonBuilder(result, <span class="hljs-keyword">null</span>, <span class="hljs-keyword">new</span> JBColor(<span class="hljs-keyword">new</span> Color(<span class="hljs-number">186</span>, <span class="hljs-number">238</span>, <span class="hljs-number">186</span>), <span class="hljs-keyword">new</span> Color(<span class="hljs-number">73</span>, <span class="hljs-number">117</span>, <span class="hljs-number">73</span>)), <span class="hljs-keyword">null</span>)
.setFadeoutTime(<span class="hljs-number">5000</span>)
.createBalloon()
.show(factory.guessBestPopupLocation(editor), Balloon.Position.below);
}
});
}</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul>
这个API,恩,我copy的源码,依然是不求记住,知道这有个类似的功能即可。
简单看一下,是通过创建一个JBPopupFactory,然后通过它创建一个HtmlTextBalloonBuilder,通过这个builder去设置各种参数,最后show。
有兴趣的可以整理各种类型的插件,比如弹出popupWindow,生成代码,生成文件类别的,然后对相关的API进行收集与整理。
这样代码写完了,先测试一下,点击RUN,然后看效果~
我们这里肯定是测试没问题的,效果图就是开始的那个gif.
如果没有问题,就可以去部署和发布我们的插件给别人去使用了。
这两部也非常简单。
四、部署插件
(1)填写插件相关信息
打开项目文件的plugin.xml,如下图:
在里面填写id,name,version等。。。记得随便填一下~
然后,点击build->prepare plugin…,如下图:
会在项目的根目录生成一个jar,如图:
这个jar就可以用于安装了。
(2)安装插件
打开Andorid Studio,选择Preferences -> Plugins -> Install plugin from disk,选择我们生成的jar即可,如图:
点击安装,然后重启即可。
好了,重启完成就可以在EDIT下看到Translate菜单了,选中单词,点击菜单或者快捷键都能实现翻译了。
就是注册账号,提交jar,填写信息,等着审核就可以了。
五、总结
终于到了总结的环节,这么长的文章其实编写插件总结起来就几句话。
- 下载Intellij IDEA,新建一个Intellij IDEA plugin的项目
- 然后在里面new Action以及编写API
- 点击prepare plugin生成jar,这个jar就可以用来安装了。