帶你全方位使用Anko庫-上篇
阿新 • • 發佈:2018-12-03
目前anko庫已更新到了0.10.8版本,這一年來的升級主要是在適配安卓版本和IDE版本以及kotlin版本上,功能並沒有多少亮眼的改動。說實話,anko庫野心不小,功能越來越多,但是感覺使用起來相對較雜亂,又沒有很詳細的文件來說明一些亮點技術的使用,上手後難免會寶山空歸。。 by 2018-11-28
目前demo工程也已升級到新版本。
kotlin的伴生庫-anko迭代了已經多個版本了,但是目前網上的資源主要集中在官方說明的機械翻譯或者舊部落格的複製/貼上上。
本文帶大家全方位的熟悉anko庫的使用。anko庫目前主要有四個核心庫
- anko-commons庫,一些通用功能,整合方式:
dependencies {
//anko_version指令碼配置,下同,本文中,該值為0.10.8
compile "org.jetbrains.anko:anko-commons:$anko_version"
}
- anko-layout庫,牛逼的dsl(領域特定語言)功能,佈局的另一種程式碼方式,相對比較簡潔,xml的簡易替代。整合方式:
dependencies { // Anko Layouts compile "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available compile "org.jetbrains.anko:anko-appcompat-v7:$anko_version" // 主要為相容一些控制元件事件的協程,不過協程coroutines目前還不是kotlin的正式內容 compile "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version" compile "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version" }
- anko-coroutines庫,整合方式:
dependencies {
compile "org.jetbrains.anko:anko-coroutines:$anko_version"
}
- anko-sqlite庫,見名知義,簡化sqlite使用的庫,整合方式:
dependencies {
compile "org.jetbrains.anko:anko-sqlite:$anko_version"
}
本篇主要介紹commons庫和layout庫的使用
這裡先附上demo工程連結
- 跳轉activity並傳遞引數,這些引數是作為extra屬性傳遞過去的,%Context/Fragment類擴充套件函式%
//啟動
startActivity<IntentActivity>("name" to "小明", "age" to 12)
//IntentActivity接收引數
var name = intent.extras.getString("name")
var age = intent.extras.getInt("age")
//若有其它設定,則&intentFor方法&構建intent
startActivity(intentFor<IntentActivity>("name" to "小紅", "age" to 13).singleTop())
- 快捷 瀏覽器,發簡訊,分享,發郵件操作,%Context/Fragment類擴充套件函式%
browse("http://m.baidu.com")
- 增強log輸出,目前發現的最大好處是支援list和map,整數,空,自定義資料類等型別的列印。缺點是1-名稱略長,tag設定不太靈活,不過tag設定也無所謂,畢竟log檢視/過濾完全可以不用tag。2-使用略麻煩,要麼實現AnkoLogger 類,要麼拿到AnkoLogger(this)變數,然後呼叫方法,不過完全可以寫個方法封裝,全域性共用,具體demo有。
verbose("tag-預設為呼叫類")//貌似不會列印,原因暫時未知
debug(110)//貌似不會列印,原因暫時未知
warn(null)
info(listOf<String>("today", "is", "a", "fine", "day"))
error(HashMap<String, String>().apply {
put("小明", "12")
put("小紅", "13")
})
warn(CData("data", 100))
...
這裡可結合一種優雅打log的方式,定製一份很強大的log方式,記得模板要宣告kotlin的applicable,比如
error("$method$($file$:$line$)\r\n -"+$text1$)
- Dimensions類,重要的方法主要是單位換算,%Context/Fragment/View類擴充套件函式%
dip(100)//dp->px
px2dip(100)//px->dp
- Helper類,重要的方法主要有三個,挺實用的
//實用的attempt函式,{}若正常執行,則value返回{}的返回值,
//若{}執行有異常,並不會閃退,只是會設定個error屬性。很好的try..catch替代方案
attempt { 3 }.value//結果3
attempt { 1 / 0 }.error
//還有sdk版本相關的
doFromSdk(21) {
info("從api 21開始列印")
}
doIfSdk(21) {
//獲得版本名也簡單的多
packageManager.getPackageInfo(packageName, 0).versionName
info("只有api 21才打印")
}
- 對話方塊的優雅彈出,%Context/Fragment類擴充套件函式%
alert("this is the msg") {
customTitle {
verticalLayout {//用到了anko-layout庫
imageView(R.mipmap.ic_launcher)//方便的設定內容
editText { hint = "hint_title" }
}
}
okButton { toast("button-ok") }
cancelButton { toast("button-cancel") }
}.show()
- 列表selector的優雅實現,%Context/Fragment類擴充套件函式%
val countries = listOf("Russia", "USA", "England", "Australia")
selector("Where are you from?", countries) { ds, i ->
toast("So you're living in ${countries[i]}, right?")
}
–其它的一些常用屬性,程式碼能簡潔不少,%Context/Fragment類擴充套件函式,有的是AnkoContext的類擴充套件屬性%
displayMetrics,defaultSharedPreferences,act
assets,ctx,contentView,resources//基本見名知義吧,不介紹了
bundleOf("name" to "test")//just show bundle,return Bundle物件
toast(".."'),progressDialog()..//使用很簡單
以上,commons庫的使用介紹完畢,應該是比較全了。
下面介紹layout庫,網上有關這個的庫的介紹比較多,主要是dsl比較cool比較潮吧,不過目前這個對簡答的佈局比較適用,複雜的還真不好說。權當語法糖熟悉下。這裡儘量只列程式碼和使用,還有一些網上少見的用法。
- 先上個常規的用法,需要注意的點是find(BTN_ID),可以在dsl外部獲得指定view
verticalLayout {
padding = dip(30)
editText {
hint = "Name"
textSize = 24f
}
editText {
hint = "Password"
textSize = 24f
}
button("Login") {
textSize = 26f
id = BTN_ID
}
}
//note
//id findview
find<Button>(BTN_ID).setOnClickListener { toast("this is login button") }
- 佈局不該放到activity中吧,否則那樣太亂了,所以第二種方案來了:
//宣告一個類繼承AnkoComponent,對應泛型類到一個LayShowActivity,然後佈局
class LayoutActyUI : AnkoComponent<LayShowActivity> {
val ET_ID = 0x1001
override fun createView(ui: AnkoContext<LayShowActivity>) = with(ui) {
verticalLayout {
val name = editText("LayoutActyUI") {
id = ET_ID
}
button("Say Hello") {
onClick {
ctx.toast("Hello, ${name.text}!")
name.textColor = 0xffff0000.toInt()
}
}
}
}
}
//然後在LayShowActivity呼叫下面的方法即可實現載入佈局
LayoutActyUI().setContentView(this)
- 引入佈局引數和一些多函式控制元件事件監聽器的簡潔使用,具體解釋見註釋
verticalLayout {
button("seekbar") {
textSize = 26f
}.lparams(width = wrapContent) {//佈局引數
horizontalMargin = dip(15)
topMargin = dip(20)
}
editText {
hintResource = R.string.app_name//直接引用資原始檔內容的方式
textChangedListener {多函式事件簡單寫法
onTextChanged { str, start, before, count ->
ai(str)
}
}
}
}
這裡補充下函式控制元件事件監聽器,比如:
//原java方式用法,必須傳入TextWatcher物件作為引數,而且有些函式根本用不上,比較麻煩。
EditText(act).addTextChangedListener(object :TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
//現在只需利用anko庫的這個寫法,使程式碼大大減少且清晰
EditText(act).textChangedListener {
onTextChanged { str, start, before, count ->
ai(str)//log..info
}
}
onClick{},onCheckedChange{},onDateChange{}
onDrawerOpen{},onItemClick{},onScrollChange{}等等都有類似用法
好了,本篇就介紹到這,下篇會對另兩個子庫做個比較全面的介紹。
附上demo工程連結。
作者劉鹹尚