Давайте посмотрим на этот пример:
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