插件開(kāi)發(fā)系列
Android Studio插件開(kāi)發(fā)1之插件介紹與環(huán)境搭建
Android Studio插件開(kāi)發(fā)2之Action System
Android Studio插件開(kāi)發(fā)3之Extensions And Extension Points(擴(kuò)展與擴(kuò)展點(diǎn))
Action System包含最基礎(chǔ)的Action,還有Action Group
Action
什么是Action
我們自己的代碼邏輯,在IDE的運(yùn)行環(huán)境下執(zhí)行咕别,我們的代碼便成了它的“插件”,可是怎樣才能讓IDE執(zhí)行我們的代碼邏輯?Intellij提供了一個(gè)很基礎(chǔ)的組件 -- Action嚣伐。
Action哭廉,直譯就是動(dòng)作,是我們最常見(jiàn)到的組件距贷,也是最普通的代碼執(zhí)行的入口柄冲。
所有菜單和工具欄的點(diǎn)擊按鈕背后就是一個(gè)Action
所以我一般都把它想象成Android里的OnClickListener。同樣地忠蝗,要自定義自己的Action现横,只需要繼承AnAction
類(lèi)并把邏輯放在actionPerformed
方法即可。
最簡(jiǎn)單的Action
public class SimpleAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
// TODO: insert action logic here
System.out.println("This is an action");
}
}
上一篇文章說(shuō)過(guò)阁最,Action是需要在plugin.xml注冊(cè)的戒祠,所以,要讓這個(gè)Action跑起來(lái)速种,還需要在plugin.xml的actions
標(biāo)簽添加以下內(nèi)容
<action id="MyPlugin.SimpleAction" class="SimpleAction" text="logAction" description="just log to console">
<add-to-group group-id="HelpMenu" anchor="first"/>
</action>
解釋一下action
標(biāo)簽的屬性的含義
- id:這個(gè)Action的唯一標(biāo)識(shí)姜盈,所有的id不能重復(fù),IDE通過(guò)id區(qū)分不同的Action
- class:這個(gè)Action的類(lèi)
- text:這個(gè)Action顯示在菜單或工具欄上的文字
- description:這個(gè)Action的描述
然后編譯運(yùn)行:
- 如果沒(méi)有用gradle點(diǎn)擊運(yùn)行按鈕即可
- 使用了gradle
- 點(diǎn)擊gradle的tool window配阵,找到Tasks / intellij / runIdea馏颂,雙擊
runIdea
- 命令行執(zhí)行
gradle runIdea
(gradle得在你的PATH里)
- 點(diǎn)擊gradle的tool window配阵,找到Tasks / intellij / runIdea馏颂,雙擊
后文將默認(rèn)使用gradle
一切正常的話,一個(gè)新的IDE實(shí)例便會(huì)運(yùn)行起來(lái)棋傍,運(yùn)行的版本取決于你在build.gradle指定的版本
現(xiàn)在救拉,在Help菜單欄的第一個(gè)條目就是我們的Action
點(diǎn)擊logAction,在控制臺(tái)(我們編譯插件的IDE實(shí)例)就能看到輸出
新建Action向?qū)?/h3>
新建一個(gè)Action那么麻煩瘫拣,Intellij那些聰明的工程師怎么會(huì)無(wú)動(dòng)于衷亿絮!
Plugin Dev插件提供了一個(gè)新建Action的向?qū)В孟裥陆ˋctivity那樣方便簡(jiǎn)單,填寫(xiě)好相關(guān)信息壹无,Action類(lèi)和plugin.xml就還幫我們建好啦
更新Action的狀態(tài)
Action中除了actionPerformed
外也值得關(guān)注的就是update
方法了葱绒,系統(tǒng)通過(guò)調(diào)用Action的update方法得到Action的狀態(tài),從而決定怎樣在菜單上顯示Action
@Override
public void update(AnActionEvent e) {
Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null) {
int lineCount = editor.getDocument().getLineCount();
if (lineCount > 20) {
e.getPresentation().setEnabled(true);
} else {
e.getPresentation().setEnabled(false);
}
}
}
上面的代碼塊意思是當(dāng)前editor打開(kāi)的文件的行數(shù)大于20行才使Action可用斗锭,否則不可用地淀,Action不可用的話是會(huì)變灰色的
Presentation還有一系列方法改變Action的“外貌”:
presentation.setDescription();
presentation.setIcon();
presentation.setText();
presentation.setVisible();
Action Group
Action Group含有一個(gè)或幾個(gè)Action Item,每一個(gè)Action都屬于一個(gè)Action Group岖是。Action Group可以被添加到菜單欄的最頂層帮毁,也可以被添加到其他Action Group,預(yù)設(shè)的Action Group非常多豺撑,除了菜單欄上的File烈疚、Edit、View等等外聪轿,還有很多Intellij已經(jīng)定義的Action Group爷肝,如上圖New Action向?qū)荆珿roups滾動(dòng)框下拉陆错,可以看到非常多的Action Group灯抛。
現(xiàn)在,手動(dòng)定義一個(gè)Action Group
<actions>
<group id="com.example.actiongroup" text="Action Group" description="this is a action group">
</group>
</actions>
<group>
標(biāo)簽同樣要被包裹在actions
標(biāo)簽內(nèi)音瓷,id是注冊(cè)Action時(shí)的要添加進(jìn)的Group的id对嚼,現(xiàn)在往com.example.actiongroup
的Group里加入Action
<group id="com.example.actiongroup" text="Action Group" description="this is a action group">
<action class="GroupAction" id="com.example.actiongroup.groupaction" text="A Action in Group" />
<add-to-group group-id="MainMenu"/>
</group>
<action>
直接寫(xiě)在<group>
內(nèi)的話就默認(rèn)是加入這個(gè)group了,同樣绳慎,group也要add到已有的group里面纵竖,才能讓它在菜單里顯示出來(lái)。這里加入的是主菜單杏愤,也就是最頂層的菜單靡砌,運(yùn)行效果如下
次級(jí)菜單展開(kāi)
現(xiàn)在添加次級(jí)菜單如下
<group id="com.example.actiongroup" text="Action Group" description="this is a action group">
<action class="GroupAction" id="com.example.actiongroup.groupaction" text="A Action in Group"/>
<group id="com.example.subgroup" text="Sub Group">
<action class="GroupAction2" id="com.example.actiongroup.groupaction2" text="A Action2 in Group"/>
</group>
<add-to-group group-id="MainMenu"/>
</group>
可是結(jié)果是這樣的
運(yùn)行結(jié)果和我們的直覺(jué)不一樣啊I睢乏奥!要如我們所愿摆舟,像次級(jí)菜單展開(kāi)的話亥曹,還需要設(shè)置一個(gè)popup屬性,把subgroup的popup屬性設(shè)置為true即可破之
添加分隔線
為相似功能的菜單項(xiàng)添加分隔線很簡(jiǎn)單恨诱,在<group>
下添加<separator/>
標(biāo)簽即可
引用Action
<group id="com.example.actiongroup" text="Action Group" description="this is a action group">
<action class="GroupAction" id="com.example.actiongroup.groupaction" text="A Action in Group"/>
<group id="com.example.subgroup" text="Sub Group" popup="true">
<action class="GroupAction2" id="com.example.actiongroup.groupaction2" text="A Action2 in Group"/>
</group>
<separator/>
<reference ref="$Cut"/>
<add-to-group group-id="MainMenu"/>
</group>
<reference>
用于引用已有的Action媳瞪,包括系統(tǒng)定義的和插件定義的Action,如上所示添加了剪切的Action
同級(jí)的Action不可引用
與<reference>
定義在同一個(gè)級(jí)別的Action不可以被引用照宝,上面的代碼塊中GroupAction是不可以被引用的蛇受,但是GroupAction2可以被引用
更新Action Group狀態(tài)
Action Group同樣通過(guò)update
方法更新?tīng)顟B(tài),不過(guò)首先先要給Action Group指定一個(gè)class厕鹃,class繼承DefaultActionGroup
<group id="com.example.actiongroup" class="MyActionGroup" text="Action Group" description="this is a action group">
<action class="GroupAction" id="com.example.actiongroup.groupaction" text="A Action in Group"/>
<group id="com.example.subgroup" text="Sub Group" popup="true">
<action class="GroupAction2" id="com.example.actiongroup.groupaction2" text="A Action2 in Group"/>
</group>
<separator/>
<reference ref="$Cut"/>
<reference ref="com.example.actiongroup.groupaction2"/>
<add-to-group group-id="MainMenu"/>
</group>
改變text和可用性
@Override
public void update(AnActionEvent e) {
e.getPresentation().setText("disable group");
e.getPresentation().setEnabled(false);
}
動(dòng)態(tài)添加Action
如果需要Action Group的Action隨條件的不同而不同兢仰,同樣需要設(shè)置group的class乍丈,不過(guò)擴(kuò)展于ActionGroup
類(lèi),并復(fù)寫(xiě)getChildren
方法把将,即可動(dòng)態(tài)的提供Action
@NotNull
@Override
public AnAction[] getChildren(AnActionEvent anActionEvent) {
return new AnAction[]{new MyAction()};
}