Android Studio插件開發2之Action System

插件開發系列
Android Studio插件開發1之插件介紹與環境搭建
Android Studio插件開發2之Action System
Android Studio插件開發3之Extensions And Extension Points(擴展與擴展點)

Action System包含最基礎的Action,還有Action Group

Action

什么是Action

我們自己的代碼邏輯,在IDE的運行環境下執行,我們的代碼便成了它的“插件”,可是怎樣才能讓IDE執行我們的代碼邏輯?Intellij提供了一個很基礎的組件 -- Action。

Action,直譯就是動作,是我們最常見到的組件,也是最普通的代碼執行的入口。

所有菜單和工具欄的點擊按鈕背后就是一個Action

所以我一般都把它想象成Android里的OnClickListener。同樣地,要自定義自己的Action,只需要繼承AnAction類并把邏輯放在actionPerformed方法即可。

最簡單的Action

public class SimpleAction extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        // TODO: insert action logic here
        System.out.println("This is an action");
    }
}

上一篇文章說過,Action是需要在plugin.xml注冊的,所以,要讓這個Action跑起來,還需要在plugin.xml的actions標簽添加以下內容

<action id="MyPlugin.SimpleAction" class="SimpleAction" text="logAction" description="just log to console">
      <add-to-group group-id="HelpMenu" anchor="first"/>
</action>

解釋一下action標簽的屬性的含義

  • id:這個Action的唯一標識,所有的id不能重復,IDE通過id區分不同的Action
  • class:這個Action的類
  • text:這個Action顯示在菜單或工具欄上的文字
  • description:這個Action的描述

然后編譯運行:

  • 如果沒有用gradle點擊運行按鈕即可
  • 使用了gradle
    • 點擊gradle的tool window,找到Tasks / intellij / runIdea,雙擊runIdea
    • 命令行執行 gradle runIdea(gradle得在你的PATH里)

后文將默認使用gradle

一切正常的話,一個新的IDE實例便會運行起來,運行的版本取決于你在build.gradle指定的版本

現在,在Help菜單欄的第一個條目就是我們的Action

2.png

點擊logAction,在控制臺(我們編譯插件的IDE實例)就能看到輸出

1.png

新建Action向導

新建一個Action那么麻煩,Intellij那些聰明的工程師怎么會無動于衷!

Plugin Dev插件提供了一個新建Action的向導,好像新建Activity那樣方便簡單,填寫好相關信息,Action類和plugin.xml就還幫我們建好啦

3.png
4.png

更新Action的狀態

Action中除了actionPerformed外也值得關注的就是update方法了,系統通過調用Action的update方法得到Action的狀態,從而決定怎樣在菜單上顯示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);
        }
    }
}

上面的代碼塊意思是當前editor打開的文件的行數大于20行才使Action可用,否則不可用,Action不可用的話是會變灰色的

8.png

Presentation還有一系列方法改變Action的“外貌”:

presentation.setDescription();
presentation.setIcon();
presentation.setText();
presentation.setVisible();

Action Group

Action Group含有一個或幾個Action Item,每一個Action都屬于一個Action Group。Action Group可以被添加到菜單欄的最頂層,也可以被添加到其他Action Group,預設的Action Group非常多,除了菜單欄上的File、Edit、View等等外,還有很多Intellij已經定義的Action Group,如上圖New Action向導所示,Groups滾動框下拉,可以看到非常多的Action Group。

現在,手動定義一個Action Group

<actions>
    <group id="com.example.actiongroup" text="Action Group" description="this is a action group">
    </group>
</actions>

<group>標簽同樣要被包裹在actions標簽內,id是注冊Action時的要添加進的Group的id,現在往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>直接寫在<group>內的話就默認是加入這個group了,同樣,group也要add到已有的group里面,才能讓它在菜單里顯示出來。這里加入的是主菜單,也就是最頂層的菜單,運行效果如下

5.png

次級菜單展開

現在添加次級菜單如下

<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>

可是結果是這樣的

6.png

運行結果和我們的直覺不一樣啊!!要如我們所愿,像次級菜單展開的話,還需要設置一個popup屬性,把subgroup的popup屬性設置為true即可破之

7.png

添加分隔線

為相似功能的菜單項添加分隔線很簡單,在<group>下添加<separator/>標簽即可

引用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,包括系統定義的和插件定義的Action,如上所示添加了剪切的Action

同級的Action不可引用

<reference>定義在同一個級別的Action不可以被引用,上面的代碼塊中GroupAction是不可以被引用的,但是GroupAction2可以被引用

更新Action Group狀態

Action Group同樣通過update方法更新狀態,不過首先先要給Action Group指定一個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);
}
9.png

動態添加Action

如果需要Action Group的Action隨條件的不同而不同,同樣需要設置group的class,不過擴展于ActionGroup類,并復寫getChildren方法,即可動態的提供Action

@NotNull
@Override
public AnAction[] getChildren(AnActionEvent anActionEvent) {
    return new AnAction[]{new MyAction()};
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容