Comments 22
Слежу за этим проектом с раннего этапа, еще когда он именовался koan) Имел каверзную дисскусию с автором, было интересно.
Насчет последнего, или пример не удачный но мне не кажется что IllegalStateException будет чем-то принципиально отличаться от NPE. Может этот делагат можно использовать как монаду?
Вы не совсем правильно поняли. Конструкция
Для справки (на всякий случай) — объект типа TextView не может принимать значение null. Для null есть типы с "?" в конце — TextView?.. Это во всем котлине. Если объект имеет тип "?", то к его полям нельзя обращаться непосредственно через "." — код просто не скомпилируется. Для этого есть операторы "?." и "!!." (сложно представить, как можно было додуматься до такого оператора:))
by Delegates.notNull()
нужна чтобы поле mHelloWorldTextView имело тип TextView, а не TextView?, чтобы не было всяких операторов типа "?." и "!!.".Для справки (на всякий случай) — объект типа TextView не может принимать значение null. Для null есть типы с "?" в конце — TextView?.. Это во всем котлине. Если объект имеет тип "?", то к его полям нельзя обращаться непосредственно через "." — код просто не скомпилируется. Для этого есть операторы "?." и "!!." (сложно представить, как можно было додуматься до такого оператора:))
Я к тому что по моему опыту textView в Activity, в 90% случаев имеет null значение не потому что ему намерено null присвоили, а потому что забыли инициализировать в onCreate(). И тут Delegates.notNull() ни разу не помощник получается. Потому и говорю про не самый удачный пример.
Опять-таки дело не в этом. Я не зря привел такой пример:
Переменную mHelloWorldTextView нужно чем-то инициализировать. А в данном случае (без Delegates) можно инициализировать только null. Тогда тип mHelloWorldTextView уже будет не TextView, а TextView?, что не хочется.
Пример предназначен только для этого.
Впрочем, Kotlin Android Extensions решает все проблемы.
private var mHelloWorldTextView : TextView = //???
Переменную mHelloWorldTextView нужно чем-то инициализировать. А в данном случае (без Delegates) можно инициализировать только null. Тогда тип mHelloWorldTextView уже будет не TextView, а TextView?, что не хочется.
Пример предназначен только для этого.
Впрочем, Kotlin Android Extensions решает все проблемы.
Гораздо лучше сделать вот так:
Во фрагментах так просто не получится, но в активити самое то.
private val mHelloWorldTextView : TextView by Delegates.lazy { findViewById(R.id.helloWorldTextView) as TextView }
Во фрагментах так просто не получится, но в активити самое то.
Вообще еще больше мне импонирует kotlinlang.org/docs/tutorials/android-plugin.html которые позволяет вообще избавиться от findViewById
Вы также можете использовать это github.com/JakeWharton/kotterknife
Да, это очень сильная вещь, я забыл упомянуть о ней.
К сожалению, подход не универсальный и не приводит у уменьшению кода, по факту это тоже самое, что и установить поле руками (ну возможна небольшая экономия на ленивой инициализации).
А что как kotlin для андроид сосуществует с DI типа roboguice или dagger? Слышал что теряется совместимость. Может есть какие-то свои альтернативы?
Может это поможет github.com/damianpetla/kotlin-dagger-example
>из тех, кто интересуется разработкой под Android, только ленивый не слышал про Kotlin
О, наконец-то я достоверно выяснил, что я ленив :)
О, наконец-то я достоверно выяснил, что я ленив :)
У меня несколько вопросов по Anko DSL.
Как применять стили?
Как использовать custom views?
Есть ли удобный способ брать размеры элеметов из dimen.xml?
Что делать если понадобится 2 разметки для portrait и landscape?
Как применять стили?
Как использовать custom views?
Есть ли удобный способ брать размеры элеметов из dimen.xml?
Что делать если понадобится 2 разметки для portrait и landscape?
Хорошие вопросы)
Во-первых, замечу еще такую вещь, что при открытии файла xml разметки во вкладке Code есть возможность конвертации в Koan DSL. Однако работает пока далеко не очень)
Теперь по вопросам:
1) Насколько я знаю, стили, описанные в xml, использовать нельзя. Это в принципе логично, все пишем в DSL (однако с dimen такое не катит, под разные размеры экрана придется в xml писать).
В общем, можно это делать с помощью функции style. Если стили где-то храним, то делаем примерно такое:
2) Custom view — легко, нужно просто знать. Пишем такую функцию (допустим, класс называется MyView):
И можем спокойно использовать:
3) Еще проще:
4) Тоже достаточно просто, создаем две разметки и в рантайме проверяем, какая ориентация:
Во-первых, замечу еще такую вещь, что при открытии файла xml разметки во вкладке Code есть возможность конвертации в Koan DSL. Однако работает пока далеко не очень)
Теперь по вопросам:
1) Насколько я знаю, стили, описанные в xml, использовать нельзя. Это в принципе логично, все пишем в DSL (однако с dimen такое не катит, под разные размеры экрана придется в xml писать).
В общем, можно это делать с помощью функции style. Если стили где-то храним, то делаем примерно такое:
private fun editTextStyle(editText: EditText) {
editText.textSize = 18f
editText.textColor = Color.RED
}
//=>
relativeLayout {
editText {
style { editTextStyle(this) }
}.layoutParams { centerInParent(); }
}
2) Custom view — легко, нужно просто знать. Пишем такую функцию (допустим, класс называется MyView):
fun ViewManager.myView(init: MyView.() -> Unit = {}) =
__dslAddView({ MyView(it) }, init, this)
И можем спокойно использовать:
relativeLayout {
myView {
//...
}
}
3) Еще проще:
val size = dip(getResources().getDimension(R.dimen.my_dimen))
4) Тоже достаточно просто, создаем две разметки и в рантайме проверяем, какая ориентация:
private fun portrait() {
linearLayout {
}
}
private fun landscape() {
relativeLayout {
}
}
//=>
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
landscape()
}
else {
portrait()
}
Спасибо! Ребота со стилями и dimen не выглядит очень удобной, учитывая что использовать сушествующие стили например из Sapport Library — совсем не тривиально. На мой взгляд весь смысл описания UI в XML это отделение разметки от кода, а в Anko объединение разметки и кода описывается как приемущество что довольно странно на мой взгляд. И еще один вопрос у меня назрел. Как в Anko можно переиспользовать разметку(аналоги layout и merge тегов)?
Автор Anko работает над удобным плагином для DSL и IDEA github.com/yanex/dsl-preview. Также у него есть стартеркит для Anko github.com/yanex/anko-template-project
1) Можно так подсунуть
<style name="TxtStyle" parent="Theme.AppCompat.Light">
<item name="android:textSize">18dp</item>
<item name="android:textColor">#ff0000</item>
</style>
relativeLayout {
ankoView({ TextView(ContextThemeWrapper(ctx, R.style.TxtStyle)) }) {
}.layoutParams { centerInParent(); }
}
Sign up to leave a comment.
Kotlin для Android