kotlinでandroid開発始めたてで、自分用のメモです。(kotlin歴2週間)
もっといい感じの使い方は恐らくあるとは思いますが、ライブラリの使い方とかサンプルコードを参考にAndroid Stdioで書いてて、勝手に補完されるので理解しておこうってレベルです。
※ちなみにJavaはあんまわからない人ですのでJavaと比べてとかはわかってないです。
リファレンス - Kotlin Programming Language が最強なのでこれ全部読めばいいと思う
変数
val num = 5 // 変更不可
var i = 0 // 変更化
var name : String = "" // 型付き
// ?を使うと「nullでなければ実行、そうでなければnullを返す」
// こうしないとnullが入れれない
var kanaName : String? = "abc"
// チェインしてもかける
val longLen = kanaName?.length?.toLong()
// Nullだったら例外が発生する
val longLenNull = kanaName!!.length()
関数
/**
* 10足して返す関数を定義
* @args i 足したい数字
* @return i + 10
*/
fun add(i: Int): Int {
return i + 10
}
// よく使う関数
// applyで自分自身になにかやる時に使う。let,with,runあたりも使うらしい
private fun onItemsLoaded(items: List<Item>) {
view?.apply {
setItems(items)
}
}
// lazy
// キャッシュ。2回目にアクセスがあった場合は最初に呼ばれたものと同じものを返す
private val service by lazy { ServiceGenerator.getClient()!!.create(ItemService::class.java) }
interface class
インタフェースは抽象メソッドの宣言と同様に、メソッドの実装を含めることができます。抽象クラスと違って、インタフェースは状態を持てません。インタフェースはプロパティを持つことができますが、これらは abstract であること、またはアクセサの実装を提供することが必要です。
interface LoginInterface {
@POST("/api/login")
fun login(@Query("mail") mail: String,
@Query("password") password: String): Call<Login>
}
今のところApiを叩く部分にしか使ってない。
square/retrofit: Type-safe HTTP client for Android and Java by Square, Inc.
data class
データクラス - Kotlin Programming Language
何もしない、データを保持するためだけのクラスを作成することはよくあります。そのようなクラスでは、いくつかの標準機能は、データから機械的に推論できます。Kotlinでは、これは データクラス と呼ばれ、 data としてマークされています。
data class User(val name: String, val age: Int)
Apiを叩いてJSONをパースしたあとの結果を保存するときによく使う。data classは継承できないのが注意
open class
クラスと継承 - Kotlin Programming Language
他のクラスがこのクラスから継承することができます。
open class BaseService {
fun buildSignature() : String {
var token: String = PreferenceManagerToken().getToken()
return md5("$token")
}
}
class ItemService() : BasePresenter() {
service.item(buildSignature()).enqueue(object : Callback<List<Item>> {
// hoge
}
}
認証を必要としたApiを呼ぶ時にいい感じに変換したtokenをくっつけて呼びたい時とかに使います。
object class
オブジェクト式と宣言 - Kotlin Programming Language
シングルトン。
class SingletonContext : Application() {
init {
instance = this
}
companion object {
private var instance: SingletonContext? = null
fun applicationContext() : Context {
return instance!!.applicationContext
}
}
}
@マークについて
ガード節
こうすることでifのネストが減って見やすくなるから好き
fun hoge(name: String?) {
name ?: return
// hogehoge
}
realmについて
番外編。kotlinの構文とは関係ないけど
Realm: Create reactive mobile apps in a fraction of the time
// どっかで最初に有効にしておく
Realm.init(this)
val config = RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build()
Realm.setDefaultConfiguration(config)
open class User: RealmObject() {
@PrimaryKey
var id : Int? = null
@Required
var mail : String = ""
}
// こんな感じ
view?.apply {
var realm = Realm.getDefaultInstance()
realm.executeTransaction {
val obj = realm.createObject(User::class.java, user.id)
obj.mail = user.mail
}
}
拡張クラスについて
既存のクラスを拡張できる機能。realmで何か取り出すみたいなのを毎回長ったらしいのを書くのが嫌なので作った。
/**
* 保存されてる最初の1件を取ってくる
*
* args Model::class.java
* return RealmObject
* 例) realm.first(User::class.java)
*/
fun <T : RealmObject> Realm.first(type: Class<T>): T? {
return this.where(type).findFirst()
}
/**
* 保存されてる指定されたIDを取ってくる
*
* args Model::class.java
* return RealmObject
* 例) realm.findId(User::class.java, 1)
*/
fun <T : RealmObject> Realm.findId(type: Class<T>, id: Int): T? {
return this.where(type).equalTo("id", id).findFirst()
}
/**
* 保存されてるデータを削除する
*
* args Model::class.java
* return なし
* 例) realm.deleteAll(User::class.java)
*/
fun <T : RealmObject> Realm.deleteAll(type: Class<T>) {
var realm = Realm.getDefaultInstance()
realm.executeTransaction {
this.where(type).findAll().deleteAllFromRealm()
}
}