前言
離上一篇文章已經(jīng)過去了挺長時間哨啃,在這期間發(fā)生了不少事烧栋,比如 Kotlin 火了,比如作者我要回老家領(lǐng)證了2333拳球。
關(guān)于 Kotlin 火了這事审姓,我一直覺得這是一門很棒的語言,不火也是祝峻。但是既然現(xiàn)在 google 都為它開路了魔吐,那么想來今后的發(fā)展應(yīng)該會很不錯。
鑒于 Kotlin 已紅遍大江南北莱找,類似的文章現(xiàn)在也如雨后春筍層出不窮酬姆,作者原來的標(biāo)題【用 Kotlin 開發(fā) Android 是一種什么樣的感受?】似乎也不那么好使了奥溺,畢竟很多 Android 開發(fā)者都已經(jīng)開始在嘗試轴踱,有的也許淺嘗輒止,有的也許會深入的使用下去谚赎,但終究在這個時間段再寫一些很基礎(chǔ)的語法文章淫僻,我個人感覺意義不大了。
最近我在用 Kotlin 做一個挺有意思的開源項目壶唤,雖然完成度還很低雳灵,但也勉強(qiáng)算是五臟俱全。這篇文章就當(dāng)做是一個引子闸盔,來介紹介紹我這個小項目悯辙,順便讓初學(xué) Kotlin 的各位了解一下,用這么一門語言迎吵,你能做出什么東西來躲撰。
DSL
應(yīng)該有不少小伙伴做過自定義 view,也知道在 Android 中自定義 view 大致分為兩種:
1.繼承于 ViewGroup击费,將多個 view 組合在一起而形成
2.繼承于 View拢蛋,在 canvas(畫布)上通過相應(yīng) API 繪制而成
因?yàn)樯蠔|家的各種奇葩需求,本人算是飽受 CustomView Hell 的摧殘蔫巩,也明白兩種方案各有適用的場合谆棱。方案1 相對來說還比較容易上手,基本會布局就會寫圆仔,而方案2 則需要一定的學(xué)習(xí)成本垃瞧,也需要一定的經(jīng)驗(yàn)去處理遇到的各式問題,最后的最后坪郭,是寫起來比較繁雜个从。那么有沒有什么辦法可以讓 canvas 繪制變得更輕松呢?
在接觸過 anko 之后,我才發(fā)現(xiàn)原來用代碼布局也可以那么優(yōu)雅那么簡單嗦锐。這里不是在給 anko 打廣告(吃瓜群眾:你口是心非)鸵隧,而是想介紹用 anko 布局時的寫法:
verticalLayout {
textView {
text = "隨便寫點(diǎn)啥"
textSize = 20f
}
imageView {
imageResource = R.mipmap.ic_launcher
}
}
諸如此類代碼,大家應(yīng)該都很眼熟:
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
沒錯意推,anko 布局和 gradle 的語法很像豆瘫,除去少量差別,你甚至?xí)X得這就是同一種語言菊值。這就是我要給大家介紹的 <b>領(lǐng)域特定語言(domain-specific languages外驱,簡稱 DSL)</b>
MagicPen
MagicPen 是我發(fā)起的一個用 Kotlin 編寫的用于操作 canvas 來自定義 view 的開源項目。似乎這么說有點(diǎn)模糊腻窒?那我們直接上代碼和圖吧
package com.lab.zhangll.magicpen
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PointF
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.lab.zhangll.magicpen.lib.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(
magicPen {
val line = line {
start = PointF(0f, 1000f) // 線條起點(diǎn)
end = PointF(1000f, 1000f) // 線條終點(diǎn)
}
val bigOne = circle {
radius = 200f // 圓半徑
aboveOf(line) // 在線條上面
leftMargin = 500f // 左邊距
bottomMargin = 10f // 下邊距
paint = Paint().apply { color = Color.RED } // 紅色
}
text {
content = "我是一只小小鳥"
paint = Paint().apply { textSize = 40f }
centerIn(bigOne)
}
circle {
radius = 50f // 半徑
centerIn(bigOne) // 在大圓中間
gesture {
onClick = { Toast.makeText(this@MainActivity, "clicked", Toast.LENGTH_SHORT).show() } // 點(diǎn)擊時彈框
onDragBy = { x, y -> moveBy(x, y) } // 跟著拖動的手指動
onRelease = { smoothMoveToOrigin() } // 放手后滑動到原點(diǎn)
}
}
}
)
}
}
算上package昵宇、import 和我有意識的空行,一共50行代碼儿子,我們看看它能實(shí)現(xiàn)出什么樣的效果吧
相信圖文結(jié)合在一起瓦哎,再加上代碼中的注釋,大家能很輕松的看明白柔逼。我像布局似的就做出了這么一個 view蒋譬。包括線條、圓愉适、文字三種圖形犯助;也包括絕對位置、相對關(guān)系维咸;甚至還有點(diǎn)擊事件剂买、拖拽事件和平滑移動動畫。挺精簡的對吧癌蓖?
可惜的是瞬哼,目前支持的功能也就這么多了,畢竟這個項目才啟動沒多長時間租副,還有兩個有意的小伙伴也得在過一段時間之后才能學(xué)習(xí) Kotlin 并加入這個項目的開發(fā)工作坐慰。不過在不久之后,MagicPen 將可以用來創(chuàng)建我能想到的大量自定義 view附井,請拭目以待讨越。
項目源碼在 https://github.com/neverwoodsS/MagicPen
歡迎各位圍觀與提出不足
PS.這是在下作為單身青年的最后一篇文章