title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url | translator | translator_url |
---|---|---|---|---|---|---|---|---|---|---|---|---|
[译]Advanced Features of Anko |
2015-05-06 03:34:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
上周我们发表了 一个新版本 的安科。虽然该库的主要目的是通过 DSL 创建布局,但即使是 XML 布局的用户也可以从中受益。今天我们来谈谈 Anko 的这种“矛盾”的特征。
启动新的Activity
的常见方法是创建一个Intent
,可能会把一些参数放入它,最后将创建的Intent
传递给上下文
的startActivity()
方法。
{% raw %}
{% endraw %}val intent = Intent(this, javaClass<SomeActivity>())
intent.putExtra("id", 5)
intent.putExtra("name", "John")
startActivity(intent)
{% raw %}
{% endraw %}有了安科,我们可以在一行代码中做到这一点:
{% raw %}
{% endraw %}startActivity<SomeActivity>("id" to 5, "name" to "John")
{% raw %}
{% endraw %}startActivity()
函数接受将作为Intent
附加参数传递的键值对。另一个功能,即具有类似语义的startActivityForResult()
也是可用的。
请参考 意图生成器函数 参考部分了解更多信息。
几乎每个应用程序都有代码,在默认的 Web 浏览器中加载一个页面,或者使用 Android Intent 打开一个新的电子邮件屏幕,所以在 Anko 中有一些辅助功能:
{% raw %}
{% endraw %}browse("http://somewebsite.org (http://somewebsite.org/)")
email("[email protected] (mailto:[email protected])", "Here I am!", "Message text")
{% raw %}
{% endraw %}其他有用的意图描述在 有意义的来电者 参考部分
Anko 提供了一种声明性的方式来创建带有短信,列表,进度条,甚至使用您自己的 DSL 布局的警报对话。 对于一个简单的文本警报,底部有几个按钮,您只需要:
{% raw %}
{% endraw %}alert("Order", "Do you want to order this item?") {
positiveButton("Yes") { processAnOrder() }
negativeButton("No") { }
}.show()
{% raw %}
{% endraw %}有一个功能可以创建和显示列表对话框:
{% raw %}
{% endraw %}val flowers = listOf("Chrysanthemum", "Rose", "Hyacinth")
selector("What is your favorite flower?", flowers) { i ->
toast("So your favorite flower is ${flowers[i]}, right?")
}
{% raw %}
{% endraw %}支持不确定和基本的进度对话框:
{% raw %}
{% endraw %}progressDialog("Please wait a minute.", "Downloading…")
indeterminateProgressDialog("Fetching the data…")
{% raw %}
{% endraw %}另外,如上所述,您可以在对话框中使用 Anko 的 DSL 来创建自定义布局:
{% raw %}
{% endraw %}alert {
customView {
verticalLayout {
val familyName = editText {
hint = "Family name"
}
val firstName = editText {
hint = "First name"
}
positiveButton("Register") { register(familyName.text, firstName.text) }
}
}
}.show()
{% raw %}
{% endraw %}通过上下文
的扩展属性可以在 Anko 中提供 Android 系统服务,例如WifiManager
,LocationManager
或Vibrator
:
{% raw %}
{% endraw %}if (!wifiManager.isWifiEnabled()) {
vibrator.vibrate(200)
toast("Wifi is disabled. Please turn on!")
}
{% raw %}
{% endraw %}可能在后台执行代码最流行的方法是将AsyncTask
子类化。但是,尽管它受欢迎,但在许多方面都是不方便的。安科有几个功能,实际上做同样但更容易使用。
async(){...}
功能在ThreadExecutor
下的{}
中执行代码。您可以使用默认的或通过自己的。
{% raw %}
{% endraw %}async(someExecutor) { // omit the parameter to use the default executor
// This code will be executed in background
}
{% raw %}
{% endraw %}如果你想回到async()
中的 UI 线程,你可以使用uiThread()
函数。
{% raw %}
{% endraw %}async {
// Do some work
uiThread {
toast("The work is done!")
}
}
{% raw %}
{% endraw %}uiThread()
在async()
中有一个特殊的语义:async()
不保存Context
实例,只有一个WeakReference
,所以即使 lambda 执行永远不会完成,Context
实例也不会泄漏。
{% raw %}
{% endraw %}async {
uiThread {
/* Safe version. This code won't be executed
if the underlying Context is gone. */
}
ctx.uiThread {
/* Here we are calling the `uiThread`
extension function for Context directly,
so we are holding a reference to it. */
}
}
{% raw %}
{% endraw %}Android SDK 提供了由几种记录方法组成的android.util.Log
类。用法很简单,但是这些方法需要传递一个 tag 参数,实际的日志消息必须是一个String
。您可以通过使用AnkoLogger
trait 来摆脱这一点:
{% raw %}
{% endraw %}class SomeActivity : Activity(), AnkoLogger {
fun someMethod() {
info("Info message")
debug(42) // .toString() method will be called automatically
}
}
{% raw %}
{% endraw %}默认标签名称是一个类名(在这种情况下为SomeActivity
),但您可以通过覆盖AnkoLogger
的loggerTag
属性轻松更改它。
每个方法有两个版本:plain 和“lazy”(只有当Log.isLoggable(tag,Log.INFO)
是true
)时,将会执行 lambda。
{% raw %}
{% endraw %}info("String " + "concatenation")
info { "String " + "concatenation" }
{% raw %}
{% endraw %}您可以阅读更多关于登录的信息 记录 参考部分。
要尝试Anko
,请遵循 这些说明 。
像往常一样,您的反馈非常受欢迎。