原文:Write an Android Studio Plugin Part 5: Localization and Notifications
做者:Marcos Holgado
譯者:卻把清梅嗅
《編寫AndroidStudio插件》系列是 IntelliJ IDEA 官方推薦的學習IDE插件開發的博客專欄,但願對有須要的讀者有所幫助。html
在本系列的第四部分中,咱們學習瞭如何在插件中集成諸如Jira Cloud Platform
之類的第三方API
,以及如何使用MVP
或MVC
之類的模式開發。本文我將部分重構插件,以便咱們能夠對插件進行本地化,並以更簡單的方式使用通知。android
今天的目標很是簡單,咱們將嘗試整理插件的代碼。爲此,我將重點關注兩個領域:通知 和 字符串。git
咱們將探索一種移除全部字符串硬編碼的使用方式,並建立將其移到一個位置的方法,就像咱們都知道的strings.xml
同樣,這也將使咱們免費進行國際化和本地化。github
此外,不一樣於往常的樣板代碼,咱們還將探索如何在建立新通知時,將相關代碼移至utils
中,咱們還將添加在通知中具備超連接的可選項,咱們將在下一篇文章中使用它。android-studio
與往常同樣,本文的全部代碼均可以在如下倉庫的Part5
分支中找到。瀏覽器
github.com/marcosholga…markdown
不管您是否已經閱讀了以前的文章,您的插件中均可能有不少字符串被硬編碼,像這樣:app
val lblPassword = JLabel("Token")
複製代碼
或者這樣oop
createNotification("Updated","Welcome to the new version", ...)
複製代碼
爲了擺脫這些硬編碼的字符串,咱們將利用 Resource Bundles,resource bundle
是一組具備相同基本名稱和特定語言的後綴的屬性文件。post
在Android
中,您能夠經過在values
文件夾中添加特定語言的後綴來本地化您的應用程序,以便英語可使用values-en/strings.xml
,西班牙語可使用values-es/strings.xml
,您可將 Resource Bundles視爲與此等效。
您的resource bundle
應存在於resources
文件夾內,我將把它們放在更深層次的messages
中,完整路徑是resources/messages/
。在其中,我將首先建立一個名爲strings_en.properties
的新屬性文件,在該文件中,我將使用如下格式以英文存儲字符串。
plugin.name = My Jira Plugin
settings.username = Username
settings.token = Token
settings.jiraUrl = Jira URL
settings.regEx = RegEx
...
複製代碼
如今咱們能夠爲另外一種語言建立另外一個屬性文件,我對西班牙語很是流利,因此我將建立一個新的strings_es.properties
文件,其內容以下:
plugin.name = Mi Jira Plugin
settings.username = Usuario
settings.token = Token
settings.jiraUrl = Jira URL
settings.regEx = Expresion Regular
...
複製代碼
若是咱們查看project
窗口,則能夠看到咱們的單個strings_en.properties
文件如何與新的strings_es.properties
一塊兒捆綁在稱爲strings
的 resource bundle 中。
要使用新的字符串,我將建立一個helper
類,該類將獲取咱們建立的字符串資源,並將基於屬性鍵返回一個字符串。
object StringsBundle {
@NonNls
private val BUNDLE_NAME = "messages.strings"
private var ourBundle: Reference<ResourceBundle>? = null
private fun getBundle(): ResourceBundle {
var bundle = SoftReference.dereference(ourBundle)
if (bundle == null) {
bundle = ResourceBundle.getBundle(BUNDLE_NAME)
ourBundle = SoftReference(bundle)
}
return bundle!!
}
fun message( @PropertyKey( resourceBundle = "messages.strings" ) key: String, vararg params: Any ): String {
return CommonBundle.message(getBundle(), key, *params)
}
}
複製代碼
若是如今咱們想要檢索插件的名稱,而不是在須要的地方對字符串進行硬編碼,咱們能夠簡單地執行如下操做:
StringsBundle.message("plugin.name")
複製代碼
如今是時候使用幫助或咱們的StringsBundle
類,使用適當的本地化字符串替換插件中的全部硬編碼字符串。:)
到目前爲止,咱們已經在不一樣的地方建立了一些通知彈窗,咱們一遍又一遍地重複相同的代碼,因此我但願簡化代碼,經過擁有一個utils
類來處理通知的建立。
在該utils
類中,我將建立一個新方法來顯示通知。此方法將具備不一樣的參數,例如標題,消息和咱們要在哪一個項目中顯示通知。Project
能夠爲空,由於在某些狀況下,咱們的通知不會顯示在Project
中,例如Project
未載入的時候。
另外一個參數是通知的類型,默認狀況下,咱們將顯示balloon
類型的通知,這是一種顯示類型,而不是通知類型,咱們能夠顯示INFORMATION
、WARNING
或ERROR
類型的通知。
最後一個參數是通知的監聽類,您可能已經注意到balloon
類型通知能夠具備一個超連接,以下例所示。
這些超連接就像咱們能夠根據須要控制的Action
,而不是將用戶重定向到打開瀏覽器中對應的URL
,咱們可使用通知監聽類指定對應的行爲。
最終方法以下所示:
fun createNotification( title: String, message: String, project: Project?, type: NotificationType, listener: NotificationListener? ) {
val stickyNotification =
NotificationGroup(
"myplugin$title",
NotificationDisplayType.BALLOON,
true
)
stickyNotification.createNotification(
title, message, type, listener
).notify(project)
}
複製代碼
如今,您可使用此方法替換舊代碼,並使用在在插件的代碼中,最終結果應以下所示:
Utils.createNotification(
StringsBundle.message("common.success"),
StringsBundle.message("issue.moved"),
project,
NotificationType.INFORMATION,
null
)
複製代碼
因爲我已經討論過使用超連接,所以我認爲我能夠再深刻一點。
我將在咱們的utils
類中添加更多的輔助方法,咱們將在下一篇文章中使用。首先,咱們將瞭解如何在通知中集成超連接。
要建立超連接,咱們須要一些html
代碼。 咱們的通知消息再也不是簡單的字符串,而是html
字符串。在html
代碼中,咱們將必須使用<a/>
標籤建立一個新的超連接,因爲我但願可以複用該代碼,所以將整個html
字符串放入咱們先前建立的資源包中。
utils.hyperlink.code = <html>{0} <a href=\"postResult.get()\" target=\"blank\">{1}</a> {2}</html>
複製代碼
您能夠看到我定義了3個不一樣的部分,咱們能夠按需修改,第一部分爲普通文本,第二部分爲超連接文本,最後是第三部分,爲普通文本的場景做準備。
經過使用resource bundle
,我能夠快速建立一個新的utils
方法,該方法將使用給定的超連接字符串前綴,超連接字符串和超連接字符串後綴返回html
代碼。
fun createHyperLink(pre:String, link: String, post: String) =
StringsBundle.message(
"utils.hyperlink.code", pre, link, post
)
複製代碼
最後,我將建立一個新的監聽Listener
,使用插件時,您可能要作的主要事情之一是容許用戶從新啓動Android Studio
,以完成新版本的安裝,或者由於您的插件剛剛進行了更改而須要重啓。
新方法返回一個Listener
,該Listener
檢測什麼時候觸發了超連接事件,並在這種狀況下從新啓動IDE
。
fun restartListener() =
NotificationListener { _, event ->
if (event.eventType === HyperlinkEvent.EventType.ACTIVATED) {
ApplicationManager.getApplication().restart()
}
}
複製代碼
以上就是本文的所有內容!如今,您應該可以將插件配置本地化,同時對一些數據進行持久化。
請記住,本文的代碼在該系列GitHub Repo的Part5
分支中可用。
在下一篇文章中,咱們將介紹模板以及如何使它們在插件中可用,保證用戶能夠經過簡單的右鍵單擊來建立新項目、模塊或任何您想要的東西。同時,若是您有任何問題,請隨時發表評論或在Twitter上關注我。
Hello,我是 卻把清梅嗅 ,若是您以爲文章對您有價值,歡迎 ❤️,也歡迎關注個人 博客 或者 GitHub。
若是您以爲文章還差了那麼點東西,也請經過 關注 督促我寫出更好的文章——萬一哪天我進步了呢?