原文: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。
若是您以为文章还差了那么点东西,也请经过 关注 督促我写出更好的文章——万一哪天我进步了呢?