前言
離上一篇文章已經過去了挺長時間,在這期間發生了不少事,比如 Kotlin 火了,比如作者我要回老家領證了2333。
關於 Kotlin 火了這事,我一直覺得這是一門很棒的語言,不火也是。但是既然現在 google 都為它開路了,那麼想來今後的發展應該會很不錯。
鑑於 Kotlin 已紅遍大江南北,類似的文章現在也如雨後春筍層出不窮,作者原來的標題【用 Kotlin 開發 Android 是一種什麼樣的感受?】似乎也不那麼好使了,畢竟很多 Android 開發者都已經開始在嘗試,有的也許淺嘗輒止,有的也許會深入的使用下去,但終究在這個時間段再寫一些很基礎的語法文章,我個人感覺意義不大了。
最近我在用 Kotlin 做一個挺有意思的開源專案,雖然完成度還很低,但也勉強算是五臟俱全。這篇文章就當做是一個引子,來介紹介紹我這個小專案,順便讓初學 Kotlin 的各位瞭解一下,用這麼一門語言,你能做出什麼東西來。
DSL
應該有不少小夥伴做過自定義 view,也知道在 Android 中自定義 view 大致分為兩種:
1.繼承於 ViewGroup,將多個 view 組合在一起而形成 2.繼承於 View,在 canvas(畫布)上通過相應 API 繪製而成
因為上東家的各種奇葩需求,本人算是飽受 CustomView Hell 的摧殘,也明白兩種方案各有適用的場合。方案1 相對來說還比較容易上手,基本會佈局就會寫,而方案2 則需要一定的學習成本,也需要一定的經驗去處理遇到的各式問題,最後的最後,是寫起來比較繁雜。那麼有沒有什麼辦法可以讓 canvas 繪製變得更輕鬆呢?
在接觸過 anko 之後,我才發現原來用程式碼佈局也可以那麼優雅那麼簡單。這裡不是在給 anko 打廣告(吃瓜群眾:你口是心非),而是想介紹用 anko 佈局時的寫法:
verticalLayout {
textView {
text = "隨便寫點啥"
textSize = 20f
}
imageView {
imageResource = R.mipmap.ic_launcher
}
}
複製程式碼
諸如此類程式碼,大家應該都很眼熟:
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 的語法很像,除去少量差別,你甚至會覺得這就是同一種語言。這就是我要給大家介紹的 領域特定語言(domain-specific languages,簡稱 DSL)
MagicPen
MagicPen 是我發起的一個用 Kotlin 編寫的用於操作 canvas 來自定義 view 的開源專案。似乎這麼說有點模糊?那我們直接上程式碼和圖吧
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) // 線條起點
end = PointF(1000f, 1000f) // 線條終點
}
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() } // 點選時彈框
onDragBy = { x, y -> moveBy(x, y) } // 跟著拖動的手指動
onRelease = { smoothMoveToOrigin() } // 放手後滑動到原點
}
}
}
)
}
}
複製程式碼
算上package、import 和我有意識的空行,一共50行程式碼,我們看看它能實現出什麼樣的效果吧
相信圖文結合在一起,再加上程式碼中的註釋,大家能很輕鬆的看明白。我像佈局似的就做出了這麼一個 view。包括線條、圓、文字三種圖形;也包括絕對位置、相對關係;甚至還有點選事件、拖拽事件和平滑移動動畫。挺精簡的對吧?
可惜的是,目前支援的功能也就這麼多了,畢竟這個專案才啟動沒多長時間,還有兩個有意的小夥伴也得在過一段時間之後才能學習 Kotlin 並加入這個專案的開發工作。不過在不久之後,MagicPen 將可以用來建立我能想到的大量自定義 view,請拭目以待。
專案原始碼在 https://github.com/neverwoodsS/MagicPen 歡迎各位圍觀與提出不足
PS.這是在下作為單身青年的最後一篇文章