Давайте посмотрим на этот пример:
package com.example
// тут как обычно, ипорт и имя пакета
import android.app.Activity
import android.os.Bundle
import android.kotlin.* // это особенный импорт, моя библиотека
import android.widget.Button
import android.app.AlertDialog
// наследование от Activity и вызов конструктора ()
class HelloActivity : Activity() {
// приватное значение для идентификации диалога.
// по сути, будет определен тип значения исходя из "1"
// ну и раз это val, то поменять уже нельзя будет
private val DIALOG_EXAMPLE = 1
// а вот мы и в onCreate. Bundle тут с "?", т.к. язык считает, что
// savedInstanceState может быть равен null
public override fun onCreate(savedInstanceState: Bundle?) {
// тут все привычно, только если использовать трэйты, то надо писать
// super<activity>.onCreate...
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
// пока ждем lazy properties, пишем локально, указывая тип в generic параметре
// и ID ресурса, и результат buttonHelllo будет Button? с id R.id.button_hello
// lazy properties, дадут возможность писать данную строку вне onCreate
val buttonHello = findView<Button>(R.id.button_hello)
// т.к. buttonHello может быть не найден, а значит - null,
// то и пишем через ?.. Kotlin дает возможность, если аргумент последний (или один)
// и является функцией, то можно убрать () и сразу писать { }
// Собственно тут я просто обвернул View.OnClickListener в функцию
buttonHello?.setOnClickListener { showDialog(DIALOG_EXAMPLE) }
}
// для создания диалога по патерну Android, нужно перегрузить эту функцию
// тут нам поможет так же патерн match. Только со словом when и аргументом id
public override fun onCreateDialog(id: Int) = when (id) {
// return тут не обязателен, т.е. сразу возвращаем результат
DIALOG_EXAMPLE -> AlertDialog.Builder(this).setTitle("Title")
?.setMessage("Hello World")
// следующие два методы так же обвернуты в библиотеке
?.setPositiveButton("Yes", {dialog, which -> })
?.setNegativeButton("No", {dialog, which -> })
?.create()
// else это как switch -> default
else -> super.onCreateDialog(id)
}
}
Как по мне, так очень наглядно, чисто и сразу ясно что написано и цель написанного. Можете представить как это выглядело бы в Java. Разумееться, если без библиотеке обверток, то разница была бы совершенно незначительной, но все же, теперь есть возможность улучшить. Пока есть одно но, но оно уже в трекере у JetBrains, называется баг. Вот такие вот кложеры как { showDialog(DIALOG_EXAMPLE) } не работают, Dalvik VM не может их найти и вываливает exception. Пока ждем, обещали профиксить.
Что касается библеотеки, так там все достаточно просто:
// View
package android.kotlin
import android.view.View
import android.app.Activity
import android.view.View.OnClickListener
// непосредственная обвертка в View.OnClickListener
fun viewOnClickListener(action: (View?) -> Unit) = object : OnClickListener {
public override fun onClick(p0: View?) {
action(p0)
}
}
// функция расширения которая вызывает обвертку. Дает возможность писать над любым View объектом
// setOnClickListener { ... }
fun View.setOnClickListener(action: (View?) -> Unit) = setOnClickListener(viewOnClickListener(action))
// Activity package android.kotlin import android.app.Activity import android.view.View // немного улучшаем findViewById, как null-безопастную и плюс generic fun Activity.findView<T: View>(id: Int) = findViewById(id) as? T // так же обворачиваем runOnUiThread fun Activity.runOnUiThread(f: () -> Unit) = runOnUiThread(runnable(f))
// Dialog
package android.kotlin
import android.app.Dialog
import android.view.View
import android.content.DialogInterface.OnClickListener
import android.content.DialogInterface
import android.app.AlertDialog
import android.app.AlertDialog.Builder
// Обвертка кложера в Dialog.OnClickListener
fun dialogOnClickListener(action: (dialog: DialogInterface?, which: Int) -> Unit): OnClickListener =
object : OnClickListener {
public override fun onClick(p0: DialogInterface?, p1: Int) = action(p0, p1)
}
// и функции расширения
fun Builder.setPositiveButton(textId: Int, action: (dialog: DialogInterface?, which: Int) -> Unit) =
setPositiveButton(textId, dialogOnClickListener(action))
fun Builder.setPositiveButton(text: CharSequence, action: (dialog: DialogInterface?, which: Int) -> Unit) =
setPositiveButton(text, dialogOnClickListener(action))
fun Builder.setNegativeButton(textId: Int, action: (dialog: DialogInterface?, which: Int) -> Unit) =
setNegativeButton(textId, dialogOnClickListener(action))
fun Builder.setNegativeButton(text: CharSequence, action: (dialog: DialogInterface?, which: Int) -> Unit) =
setNegativeButton(text, dialogOnClickListener(action))
Я считаю это очень доступно и читабельно. Скорость компиляции приемлимая, остаеться ждать и надеяться, что язык выстрелит. На этом все, до скорого.
No comments:
Post a Comment