Разное

Anko kotlin: Kotlin-библиотека Anko стала deprecated / Блог компании JUG Ru Group / Хабр

Содержание

Kotlin-библиотека Anko стала deprecated / Блог компании JUG Ru Group / Хабр

У проекта Anko, призванного улучшить Android-разработку на Kotlin, более 15 000 звёзд на GitHub, то есть это одна из самых известных Kotlin-библиотек. Однако теперь было официально объявлено о прекращении работы над ней.

Компания JetBrains представила эту библиотеку в 2015-м, когда Kotlin ещё не был официально поддерживаемым языком разработки для Android, но отдельные мобильные разработчики уже им заинтересовались. Исходным назначением Anko была удобная работа над UI прямо в Kotlin-коде (а не в отдельных XML-файлах). Позже, помимо этого, активно обратились и к другим Android-задачам: например, к работе с SQLite.

Библиотека привлекла внимание разработчиков и попала во многие приложения, в какой-то степени поспособствовав успеху Kotlin на Android. Однако, как признают в прощальном тексте её создатели, полностью воплотить идеи не удавалось из-за ограничений платформы и дефицита ресурсов. А тем временем в Android-разработке многое изменилось: для работы с SQLite компания Google представила новый инструмент Room, для работы с UI — Jetpack Compose, для различных других задач — Android KTX.

В результате сложилась ситуация, когда Kotlin стал приоритетным языком Android-разработки, но поспособствовавшая этому библиотека не разделила с ним успех, а становилась всё менее актуальной. Её разработка соответствующим образом затухала, и с февраля 2019-го в проекте не было ни одного коммита. Поскольку Anko по-прежнему используется, сообщество задавало вопросы о будущем проекта. И теперь получило ответ: прекращение работы над проектом, де-факто уже произошедшее, было закреплено официальным сообщением.

Если по такому поводу хочется поностальгировать — можно посмотреть доклад с Mobius 2016 года от Яна Жуланова (основного разработчика Anko), частично посвящённый этой библиотеке. На момент этого выступления и Kotlin, и Anko в мире Android были многообещающими новичками.

Kotlin

Статья проплачена кошками — всемирно известными производителями котят.

Если статья вам понравилась, то можете поддержать проект.

Любой кот линяет. Из выпавшей шерсти можно собрать второго кота. По такой же аналогии из Java можно создать новый язык Kotlin, образованный из двух слов Kot linяет. Есть ещё неправдоподобная версия об острове в Финском заливе, которая просто смешна и не заслуживает внимания.

17 мая 2017 года на Google IO объявили о поддержке Kotlin в Android Studio 3.0. Пора учить новый язык, который заслужил много лестных отзывов от опытных разработчиков.

Что нового

3 марта 2020 года вышла версия 1.3.70. Новые классы и функции для коллекций. 64 — 1).

Новый мультиплатформенный класс kotlin.random.Random: println(Random.nextInt(43))


28 ноября 2017 года вышла новая версия Kotlin 1.2.

Добавлены новые функции для изменяемых списков: fill, replaceAll, shuffle.

Добавлена новая функция shuffled для неизменяемых списков.

Добавлены математические функции. Например, можем узнать, что число является отрицательным.


val item = -100
println("${item.sign}") // вернёт -1

Продолжить изучение Kotlin

Сконвертировать существующий Java-код на Kotlin можно через меню Code | Convert Java File to Kotlin File.

Если скопировать в буфер обмена код на Java и вставить его в kt-файл, то студия автоматически сконвертирует код.

На заметку: Файлы с кодом на Kotlin смотрятся странно в папке java в проекте студии. Открываем файл gradle.build модуля и в секции android добавляем блок:


sourceSets {
    main. java.srcDirs += 'src/main/kotlin'
}

Переключаемся в режим Project и переименовываем папку java. Приложение будет работать по-прежнему. В режиме Android по-прежнему будет видна папка java, это жестко прописано в студии. Может потом поправят этот момент.

Tools | Kotlin

Также в студии есть целый раздел меню для настройки: Tools | Kotlin.

Show Kotlin Bytecode

При выборе Show Kotlin Bytecode можно просматривать любой файл *.kt, в отдельном окне будет виден байткод файла. Если в нём не будет данных, которых нельзя представить в Java, то также будет доступна возможность декомпилировать его в Java-код кнопкой Decompile.

Kotlin REPL

Интересная оболочка в виде командной строки. Можно быстро написать какое-то выражение и получить результат.

Anko

Библиотека Anko была специально разработана для удобного программирования под Android, сокращая количество кода для вызовов намерений, диалоговых окон, журналирования и т. д.

Спустя четыре года её объявили устаревшей и поддержка прекратилась. А всё почему? Выбрали какое-то непонятное название. Назвали бы Barsik, тогда все бы использовали её.

Примеры на Kotlin

Android KTX

Щелчок кнопки/Счётчик ворон

Переключение между экранами приложения

Счётчик шагов

Запускаем фотосъёмку через Intent

Запускаем съёмку видео через Intent

ShareActionProvider (Провайдер действия передачи информации)

Android: ValueAnimator

RxKotlin

Книги

Книга, выпущенная в 2020 году Head First. Kotlin (на русском)


Первая книга на русском языке «Kotlin в действии». В начале книге перечисляются благодарности, в том числе — Наконец, мы хотели бы поблагодарить наши семьи и котов за то, что они делают этот мир лучше.

Реклама

За что Kotlin так полюбили в Google и кому нужны две тысячи языков программирования

Язык программирования Kotlin, разработанный петербургской компанией JetBrains, стал официальным языком разработок для Android. Об этом официально объявили на конференции Google I/O. Командой Kotlin руководит выпускник Университета ИТМО Андрей Бреслав. Почему именно Kotlin так полюбился IT-гиганту среди многих других «молодых» языков, как и зачем вообще появляются новые языки программирования, читайте в комментариях экспертов и информационной подборке ITMO.NEWS.

Как разрабатываются языки программирования

По разных подсчетам, в мире уже более двух тысяч разных языков программирования. Для старых языков постоянно выходят обновления, а также появляются новые языки. Когда синтаксис языка не меняется, а лишь усложняется и дополняется, разработчику достаточно немного потренироваться, чтобы продолжать писать на любимом языке. Иногда же меняется сама структура языка, и тогда программисту подчас приходится переучиваться, адаптируясь к обновленному языку. Обычно переход на новую структуру идет постепенно и частями, то есть только 10-20% программного кода начинает писаться с помощью нового языка.

«Программисты не были абсолютно довольны языками С++ и Java, потому что это достаточно сложные языки, при этом первый сложнее, чем второй. Поэтому появился язык Scala, который нравится многим программистам, но и он весьма сложен. Огромный опыт компании JetBrains в создании средств разработки программ для разных языков программирования позволил за семь лет создать язык Kotlin, который полностью совместим с Java, но проще и удобнее его. Языки программирования разрабатываются постоянно, задачу сделать универсальный язык уже никто перед собой не ставит. Несмотря на это, каждый язык более эффективен в определенной области, где его чаще всего и используют. Есть даже такое направление в создании языков, когда они разрабатываются под конкретную предметную область», – прокомментировал заведующий кафедрой технологии программирования Университета ИТМО Анатолий Шалыто.

Анатолий Шалыто

Сегодня некоторые компании даже составляют свои рейтинги языков. Например, компания TIOBE, которая специализируется в оценке качества программного обеспечения, ежемесячно вычисляет индекс популярности тех или иных языков с 2001 года. В генерируемом списке 50 строчек, и чтобы язык программирования попал в индекс, разработчики должны написать соответствующее письмо в компанию. Подсчет ведется на основе данных 25 поисковых Интернет-систем. Пока в рейтинге с большим отрывом лидирует Java, за ней идет С. При этом составители списка подчеркивают, что за последний год оба языка программирования стали менее популярными, примерно на 6%. При этом TIOBE показывает, что язык С был языком №1 вплоть до 2002 года, а Java в 1997 году была на 14 месте, но уже через пять лет заменил С на первой позиции.

Отличную лекцию по истории развития языков можно послушать здесь: о том, как появились языки С, PHP, Ruby и Java рассказывает куратор академических программ «Яндекса», директор центра студенческих олимпиад факультета компьютерных наук ВШЭ Михаил Густокашин. Лектор подчеркивает, что для каждой задачи следует выбирать разный язык программирования. Например, он говорит, что для военной промышленности лучше всего писать на старом-добром Pascal – языке, который родился еще в 1970 году! Почему? Потому что он надежней. Приложения для бизнеса можно писать на Java, потому что этот язык тоже достаточно надежен, но гораздо более прост в использовании. Эксперт также подчеркивает, что важно поддерживать интерес к языку среди программистов с помощью создания сообщества разработчиков, которые пишут на этом языке. Если вокруг какого-нибудь нового языка создается инфраструктура, собираются люди, которые им пользуются, только тогда язык станет популярным. Кстати, разработчики Kotlin тоже взяли на вооружение эту стратегию.

Немного о  Kotlin

Язык программирования Kotlin начал разрабатываться в петербургской компании JetBrains в 2010 году. Официальный релиз продукта был выпущен в 2016 году. Такое название язык получил в честь острова в Финском заливе, на котором расположен Кронштадт. По интересному совпадению, название популярного языка Java – это тоже имя острова в Индонезии. Вероятно, совпадение не случайно. Как сообщается в пресс-релизе, Kotlin должен работать везде, где работает Java, и один из ориентиров был сделать такой продукт, который можно будет использовать в смешанных проектах, которые создаются на нескольких языках.

Язык программирования Kotlin. Источник: cdn-business.discourse.org

Как отмечают авторы Kotlin,  самое главное для них было создать «прагматичный» продукт. Это значит, что они фокусировались не только на устранении ошибок и совершенствовании продукта, что делал бы любой программист-разработчик, а хотели сделать именно полезный инструмент.

«Инструменты разработки, включая языки программирования, постоянно развиваются. Языки отличаются от других инструментов тем, что их довольно сложно развивать эволюционно. Новая версия языка должна поддерживать все уже существующие программы. Это ограничивает возможности развития существующих языков и создает потребность в появлении новых. Фактор, который определяет успешность нового языка программирования, это, в первую очередь, удобство для разработчиков. Кроме краткости и выразительности, Kotlin хорошо совместим с кодом на Java: можно использовать все существующие библиотеки и даже смешивать код на двух языках в одном проекте, поэтому не возникает особенных сложностей с переходом», – прокомментировал Андрей Бреслав, руководитель проекта Kotlin в JetBrains, выпускник Университета ИТМО.

Почему Google полюбил Kotlin

На официальном сайте разработчики Android пишут, что они наблюдали «восхождение» Kotlin все последние годы. «Гуглеры» не стесняются описывать этот язык как впечатляющий и лаконичный, который отрывает больше возможностей и с которым приятно работать. Он обладает повышенной производительностью: программный код на нем получается в среднем на 40% короче, чем на других языках, а также Kotlin позволяет не допускать некоторые ошибки в коде. Одним из определяющих факторов популярности Kotlin в Google стало то, что он совместим с Java, который уже используется при разработке приложений под Android.

Теперь, когда программисты начинают создавать новое приложение в официальной среде  разработки Android Studio, они сразу могут включить плагин «поддержка Kotlin». Также можно конвертировать уже созданные строки кода на других языках в язык Kotlin, вставлять блоки на других языках в строки кода на Kotlin. В будущем для языка будет разрабатываться больше библиотек и инструментов, больше обучающих материалов, проще будет найти решения для возможных проблем.

«Отсутствие гарантий поддержки языка со стороны Google отпугивало многих разработчиков от перехода на Kotlin. Даже если язык очень нравится,  программист всегда думает о риске, что в какой-то момент этот язык просто перестанет работать. Теперь есть гарантия того, что работать Kotlin не перестанет, и мы ожидаем, что количество пользователей языка резко возрастет. Было бы естественно предположить, что многие компании со временем перейдут на Kotlin полностью, хотя технически их к этому ничего не вынуждает, это просто вопрос предпочтений», – подчеркнул Андрей Бреслав.

Он добавил, что Kotlin очень активно развивается. Команда разработчиков сейчас работает над билд-системой, скоростью компиляции, улучшает производительность IDE, добавляет в инструментарий новые возможности, в том числе связанные с интеграцией в Android Studio. Также идет работа над мультиплатформенными проектами (возможность компилировать один и тот же код под несколько платформ), целый ряд языковых улучшений находится в стадии дизайна.

Андрей Бреслав

В Google также подчеркнули, что их вдохновляет концепт языка Kotlin, по которому он всегда был и останется бесплатным для разработчиков, то есть open source project. Это значит, что язык не привязан к какой-либо отдельной компании, а исходный код распространяется под свободной лицензией. Загрузить продукт можно здесь. Чтобы поддерживать развитие Kotlin, компаниями Google и JetBrains будет создано некоммерческое партнерство. Также в рамках «миссии» Android очень важно, что авторы Kotlin создают вокруг своего продукта сообщество людей, которые профессионально занимаются разработкой на этом языке и любят делиться опытом. Например, в ноябре в США состоится конференция Kotlin, также разработчики могут получать ежедневные новости и советы о программном продукте, встречаться на местном уровне.

Кстати, сам проект Android Studio был разработан на базе программной среды разработки IntelliJ IDEA, которую также создали в компании JetBrains. Но несмотря на тесной сотрудничество, в петербургской компании подчеркивают, что ни о какой продаже JetBrains американскому IT-гиганту речи не идет. При этом Koltin не будет заточен только под Android. Цель компании – сделать язык программирования подходящим под разные платформы разработки.

Перейти к содержанию

Особенности перехода на Kotlin для Android-разработчиков

Сегодня все большее число программистов, занятых в сфере разработки под Андроид, активно используют Kotlin. Этот современный язык рекомендует Google, да и многочисленные отзывы в сообществах подтверждают удобство и универсальность ЯП.

Kotlin уже показал себя на практике, завоевал доверие. И если вы решились в рамках какого-то проекта отказаться от привычного Java в пользу Kotlin, скорей всего, вы об этом не пожалеете. Но при этом важно понимать, с чего начать, и какие «подводные камни» вас ждут в процессе изучения нового ЯП.

Экскурс в историю

Разработчиками платформы Kotlin стала чешская компания JetBrains. Продукт создавался как язык, ориентированный на создание приложений для мобильных устройств, но и в веб-разработке он показывает прекрасные результаты.

Разработка велась с 2010 года. Первая рабочая версия Котлин вышла в 2016 году в середине февраля. В проект было вложено более 15 млн. $. На данный период времени наиболее актуальной версией продукта считается Kotlin 1.2, релиз от ноября 2017 года.

Язык создавался под работу с JVM (Java Virtual Machine), которая является главной исполняющей системой Java. Фактически при работе с Kotlin виртуальная машина компилирует программу в байт-код. Это позволяет запускать приложения, написанные на этом языке, в любой среде, где присутствует виртуальная машина Java, в том числе, в любом браузере.

Характерная особенность языка – написание приложений под четко определенную платформу (нативные приложения) с учетом всех ее характеристик и условий работы. Но также реализована возможность компиляции в двоичный код, что позволит программе работать без Java-машины. В итоге мы получаем очень широкий круг возможностей.

Код, написанный на Kotlin, может без проблем взаимодействовать с разными ОС.  Сегодня язык активно развивается в сторону open source, т.е. разработка его становится массовой, как и у любого популярного продукта с открытым кодом.

На то, как выглядит современный Kotlin, оказало влияние большое количество других языков программирования. Разработчики использовали лучшие идеи из других языков, в результате синтаксис получился простым и удобным, а писать на Kotlin можно в разных стилях, в том числе, применять функциональное программирование или ООП.

В 2017 году компания Google включила Котлин в список официальных языков для разработки приложений платформы Android. Инструменты языка поддерживаются в Android Studio, начиная с версии 3.0.

Что полезного содержит Kotlin

Авторы языка не пытались изобрести, что-то абсолютно новое. Прежде всего, они хотели создать удобный инструмент для девелоперов, способный решать поставленные задачи лучше и быстрее, чем предшественники.

Самые интересные «фишки», которые оценили в Kotlin разработчики:

  • Null Safety. Одна из самых часто упоминаемых особенностей языка. Позволяет при определении типов, переменных, полей и т.д. самостоятельно определять, может ли в них находиться ссылка на null.
  • Лямбды. Возможность не только объявлять функции в рамках пакета, но и передавать их в качестве параметра для других функций. Возможность, реализованная во многих языках. Но в Java ее сильно не хватает.
  • Extension methods. Возможность определить метод для выбранного типа отдельно от объявления самого типа. Помогает разгрузить интерфейс для утилитарных методов.
  • Делегирование. Возможно двумя методами – делегирование всех методов к определенному инстансу либо delegated properties, при котором делегируется доступ к выбранным свойствам объекта.
  • Generics. Это практически те же самые дженерики, что хорошо известны всем Java-разработчикам. Но в Котлине их доработали и сумели исправить множество недочетов.
  • Data-классы. Возможность генерировать специальные классы, единственное назначение которых состоит в хранении данных. После описания компилятор извлекает члены класса из свойств, которые описаны в коде конструктора. Есть у этой возможности плюсы и минусы, функционал относительно ограничен и нуждается в доработках. Но само наличие

Есть и другие интересные решения в Котлин, все их описывать – придется создавать целое руководство. А это совсем не наша цель. Потому давайте вернемся к тому, с чего мы и начинали. И разберемся в особенностях Kotlin и «подводных камнях» для разработчиков, которые решили «пересесть» с привычного Java на этот язык.

Начинаем знакомство

Основные настройки Котлин и проекта на нем вы можете узнать из документации, там все описано очень подробно и понятно. А мы будет говорить преимущественно об особенностях и нюансах перехода проекта с Java.

Если вы пользуетесь средствами annotation processing или основанными на нем библиотеками, придется вносить правки в модули build.gradle. Без подключения дополнительного плагина kapt они просто не будут собираться.

Вот так выглядит код подключения:

[code]apply plugin: ‘kotlin-kapt'[/code]

Также не забудьте в конфигурации build.gradle заменить все инициированные annotationProcessor на тот же kapt.

Все гибернированные стабы будут поддерживаться автоматически из-под-коробки Ну, а в особенностях установки вы разберетесь без проблем самостоятельно.

Null Safety: как это работает

Основное отличие Котлин от Джава – это поддержка null-safety типов. Используются такие описания типов для того, чтобы избежать обращения к null значениям, распространенного бага, который в среде программистов известен под названием «ошибка на миллион» или NPE (NullPointerException).

Причина, по которой может возникнуть ошибка это:

  • throw NullPointerException() – явный вызов, инициированный программистом.
  • Использование NPE в !! операторе.
  • Любое несоответствие данных при инициализации.
  • Интероперабельность платформы Джаба:
    • Попытки доступа к элементу на null референции типа платформы;
    • Обобщенные типы, используемые для Java интероперабельности с некорректной допустимостью;
    • Прочие проблемы с внешним java кодом.

Котлин позволяет при написании кода с самого начала «закрыть» возможность появления этого бага. Это большой плюс, но джава-разработчикам придется привыкать своевременно описывать типы.

Data классы в Котлин

Перед тем компания Google объявило об официальной поддержке Котлин, нередко встречались советы начать знакомство и переход на этот язык с создания на нем юнит-тестов. Многие были с этим согласны, поскольку это было самым неагрессивным способом захвата кодовой базы. Также подобный подход освобождал от риска получения ошибок, вызванных применением двух языков программирования в одном проекте. Напоминаем, что unit-тесты относятся к императивному стилю программирования.

Предположим, что вам нужно указать класс для видеофайла. В этом случае будет достаточно написать:

[code]data class Movie(val id: Long, val title: String, val director: String, val releaseDate: Date)[/code]

В итоге мы получаем целый перечень преимуществ. И особенно выедается среди них лаконичность кода.

Кроме того, стоит обратить внимание на такие особенности:

  • Переопределенные методы находятся «под коробкой».
  • Immutable неявно наследуется от Any. Его создание в коде выглядит так:
    Movie(42L, «Isle of Dogs», «Wes Anderson», Date())
  • Метод copy () поможет легко «клонировать» фрагмент данного класса, который будет не изменяем, но отличаться одним или несколькими полями если не было применено значение «private». Такое решение станет, по сути, первым шагом к функциональному стилю программирования:
    val clonedMovie = existingMovie.copy(id = 43L)

Напомним, что для Java в функции copy() необходимо работать со значением каждого поля. В Котлин все намного проще.

Учтите, что этот метод работает только с data-классами, для обычных он не применим.

Еще один интересный плюс. Вместо обычного Builder-паттерна – значения «по умолчанию:

[code]data class Movie(val id: Long = 0L, val title: String = «», val director: String = «», val releaseDate: Date, val description: String? = null)

val movie = Movie(releaseDate = Date(), title = «The Darjeeling Limited»)
[/code]

О чем бы еще хотелось сказать. Дата-классы в рамках средств Котлин не наследуют друг друга. Но можно применить sealed-классы (запечатанные классы), они не могут быть созданы непосредственно и могут иметь абстрактные элементы. Как вы уже поняли, для объявления этого класса применяется идентификатор sealed.

Data-классы и Parcelable: польза или вред

Начиная с версии 1.1.4 в Котлин реализована аннотация с именем «@Parcelize». Она позволяет отказаться от необходимости писать boilerplate-реализации для использования де/сериализации объектов. Выглядит это так:

[code]@Parcelize

data class Movie(val id: Long, val title: String, val director: String, val releaseDate: Date)[/code]

Не следует забывать о том, что необходимо применить AEp:

[code]apply plugin: ‘kotlin-android-extensions'[/code]

Непременно необходимо обозначить experimental-флаг как «истина»:

[code]android {

  androidExtensions {

      experimental = true

  }

}[/code]

Это решение пока что имеет статус экспериментального, т.е. код API еще будет обновляться и дорабатываться. А это значит, что в нем могут присутствовать определенные еще не выявленные баги.

Data-классы и самые востребованные библиотеки

Чтобы пользоваться всеми возможностями популярной библиотеки Room Persistence Library, достаточно подключить kapt. После этого вы с легкостью можете описывать различные объекты, как для исполнения на сервере, так и для работы в браузере.

Пример кода:

[code]@Entity(tableName = «movies»)

data class Movie(

       @PrimaryKey @ColumnInfo(name = «id») val id: Long,

       @ColumnInfo(name = «title») val title: String,

       @ColumnInfo(name = «director») val director: String,

       @ColumnInfo(name = «date») val releaseDate: Long

)[/code]

С модификатором Nullable также не возникнет никаких проблем. Разочарование вас ждет только при попытке работать с Room, так как здесь не поддерживаются значения по умолчанию. Кроме того, могут возникнуть и другие сложности. (о них стоит почитать в документации).

Язык поддерживает практически все привычные вам библиотеки. Он прекрасно сочетается с популярным в настоящее время JSON, не требует никаких дополнений или конвертеров. Поэтому все библиотеки будут сериализованы, как и в самом обычном Java.

[code]data class Movie(

       @SerializedName(«id») val id: Long,

       @SerializedName(«title») val title: String,

       @SerializedName(«director») val director: String,

       @SerializedName(«releaseDate») val releaseDate: Date

)[/code]

Но и здесь значения по умолчанию не поддерживаются.

Если вам требуется для работы Jackson, нужно добавить поддержку специального модуля поддержки сериализации. А для комфортной работы с Moshi необходимо прописать зависимость:

[code]implementation ‘com.squareup.moshi:moshi-kotlin:1.x.y'[/code]

Как свести Kotlin с Java

По идее, постепенно весь ваш проект перейдет с Java на Котлин. Но до этого придется пройти тернистый путь. Некоторые нюансы решаются просто, другие могут заметно «испортить жизнь», как минимум на 2-3 часа.

В принципе, Kotlin создавался как 100% совместимый с Джава. Вы без проблем сможете пользоваться в коде Котлин существующими Java-классами и другими объектами, а также, наоборот, применять в коде Java аннотации и классы из Котлин. Но существуют некоторые ограничения, все они есть в документации. В случае возникновения ошибки рекомендуем с ними ознакомиться подробнее здесь.

Going Static

Обратите внимание, в языке Котлин нет слова static. Но это не повод для паники. Сам механизм, который позволяет объявить объект внутри созданного класса, заимствует все доступные функции описания, никуда не делся. Только теперь это называется «companion object». Но если вы хотите, чтобы компиляция прошла полноценно и для объекта, и для статистических методов классов, не забудьте добавить метку @JvmStatic.

Коллекции

Котлин при работе с коллекциями фактически полностью повторяет протокол, предусмотренный в Джава. Но при этом язык имеет также собственные интересные возможности. Благодаря встроенным модификаторам для объявления, преобразования и модификации коллекций (listOf(), mapOf(), etc)  возможности разработчика расширяются. В работе эти функции показали себя как очень удобные.

Напомним, что коллекция – это массив данных, который вносится в тело программы и не подлежит изменению извне. Внутри программы операторы сработают. А в случае попытки каких-то изменений, в том числе, при помощи кода Котлин из других программ, вы можете получить на выходе UnsupportedOperationException, что, в принципе, вполне логично.

Несколько слов о unit-тестах

При написании тестов под бизнес-логику ваших приложений (а писать их нужно в обязательном порядке), скорей всего, вы традиционно пользуетесь Mockito. И здесь может возникнуть проблема.

Дело в том, что со стороны Mockito из-под-коробки не предусмотрена работа с к final-классами. А в Котлин по умолчанию все классы имеют статус final по умолчанию. Вариант open нужно объявлять явно.

Решить эту проблему можно одним из двух методов — объявить все классы как open или использовать простой хак:

  1. Зайдите в папку …/resources/mockito-extensions
  2. Создайте файл org.mockito.plugins.MockMaker.
  3. Внесите в него строку: mock-maker-inline.

Множество других полезных возможностей и решений вы найдете в библиотеке mockito-kotlin. Она поможет сделать удобнее инициализацию моков, верификацию и т.д.

Kotlin и Data Binding

При использовании в джава-проекте DataBinding в случае перехода на Котлин может появиться множество ошибок компиляции. Чтобы избежать их и восстановить совместимость, добавьте в файл со списком зависимостей строку:

[code]kapt ‘com.android.databinding:compiler:x.y.z'[/code]

Кроме того, обязательно изучите полезный плагин Kotlin Android Extensions. Он позволит вам отказаться от DataBinding, а реализация многих функций с его помощью становится настолько простой, что в него невозможно не влюбиться.

Резюме

Несмотря на декларируемую 100% совместимость Kotlin с традиционным Java, переход существующего проекта, как видите, может сопровождаться определенными сложностями и багами. В статье мы привели только отдельные, скажем так, базовые примеры подобных проблем и показали их решение. В реальности «подводных камней» окажется намного больше.

Но есть и хорошая новость. Решение возникших сложностей вы практически всегда найдете в документации Котлин или профессиональном сообществе. Чаще всего реализация их оказывается совсем несложной. А переход на Котлин стоит того, так как язык позволит сделать проект быстрее, подарит новые возможности в разработке, да и программировать на Котлин – одно удовольствие. Конечно, после того, как вы его изучите.

Null Safety, Extension Methods и прочие крутые штуки — «Хакер»

Содержание статьи

Во время написания этой статьи произошло очень большое событие — Kotlin был признан официальным языком программирования для платформы Android. Год назад мы уже писали про этот язык, но жизнь не стоит на месте, и в этой статье я расскажу тебе, какими фичами Kotlin смог покорить меня, старого и закаленного программиста. 🙂

Уже много лет как JVM — это не просто виртуальная машина, в байт-код которой компилируется язык программирования Java, а нечто куда большее. Сегодня JVM — это платформа, для которой существует множество популярных языков программирования, таких как Scala, Groovy и Clojure. Kotlin — еще один язык в этом ряду, и он обладает целым рядом преимуществ и особенностей. Сейчас это уже не только язык для JVM, есть варианты для JavaScript и даже Kotlin Native, что очень добавляет ему привлекательности.

Меня вряд ли можно назвать оголтелым патриотом, но мне очень приятно думать, что языком программирования, который создается в России, пользуются люди по всему миру.

Почему «создается», а не «создан»? Дело в том, что языки программирования эволюционируют, и это нормально (кроме случая C++ — ну же, ребята, хватит уже). Поэтому все, что здесь описано, верно здесь и сейчас (а дальше, уверен, будет только лучше).

 

Классы и объекты

Начнем с простого — с ООП. В статье я буду акцентировать внимание на необычных с точки зрения Java моментах.

В языке Kotlin первичный конструктор не может содержать кода и код должен быть вынесен в блок инициализации.

class Customer(name: String) {
    init {
        logger.info("Customer initialized with value ${name}")
    }
}

Однако дополнительные конструкторы мало чем отличаются от аналогов в Java:

class Person {
    constructor(parent: Person) {
        parent.children.add(this)
    }
}

Если же первичный конструктор содержит параметры, то другие конструкторы должны делегировать (явно или неявно через другой, вторичный конструктор) создание объекта первичному конструктору:

class Person(val name: String) {
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}

Здесь еще есть неизменяемое поле name, теперь оно часть класса. Конечно, можно сделать конструктор непубличным, например так:

class DontCreateMe private constructor () {
}

Наверное, самая интересная особенность — это отсутствие ключевого слова new в Kotlin. Чтобы создать объект, нужно просто вызвать соответствующий конструктор:

val invoice = Invoice()

val customer = Customer("Joe Smith")

В Kotlin аналог ObjectAny, базовый класс для всех классов, хотя это аналог только в смысле корня иерархии, он не имеет equals(), hashCode() и toString().

Все классы в Kotlin по умолчанию final, от них нельзя наследовать, и, чтобы сделать класс открытым для наследования, нужно объявить его как open:

open class Base(p: Int)

class Derived(p: Int) : Base(p)

Это же касается и методов, которые можно переопределять, они также должны быть помечены как open:

open class Base {
    open fun canOverride() {}
    fun cannotOverride() {}
}

class Derived() : Base() {
    override fun canOverride() {}
}

С этим связано несколько правил, в том числе следующее: только открытый класс может иметь открытые методы. Более того, методы, помеченные override, являются также open-методами. Для того чтобы закрыть override-метод, нужно использовать final:

open class AnotherDerived() : Base() {
    final override fun v() {}
}

Kotlin лаконичен и последователен, override может быть частью первичного конструктора:

interface Foo {
    val count: Int
}

class Bar1(override val count: Int) : Foo

class Bar2 : Foo {
    override var count: Int = 0
}

Теперь пару слов про ООП, скажем так, в экзотическом стиле: абстрактные классы, конечно, есть и в Kotlin, но, что интересно, непустой открытый метод может быть переопределен пустым в абстрактном наследнике!

В Kotlin нет статических методов, и создатели языка рекомендуют пользоваться функциями на уровне пакета (то есть не привязанными к конкретному классу). Если мы все-таки хотим иметь что-то похожее на статические методы в Java, то есть ненаследуемые, но как-то привязанные к классу, то типичный пример здесь — это фабричный метод (factory method), когда мы можем воспользоваться возможностью создания объекта-компаньона. Для тех, кто программирует на Scala, это все очень знакомо:

interface Factory<T> {
    fun create(): T
}

class MyClass {
    companion object : Factory<MyClass> {
        override fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()

Если же мы хотим получить сам объект-компаньон, это можно сделать так:

class MyClass {
    companion object {
    }
}

val x = MyClass.Companion

Более того, существует еще так называемое объектное выражение, но эту тему мы оставим до следующей статьи, а желающие могут найти все, что необходимо, в первоисточнике — KotlinLang.org.

 

Свойства

Свойства (properties) — весьма полезный инструмент программирования, и надо сказать, что в Kotlin этот вопрос решен очень интересно:

val isEmpty: Boolean
    get() = this.size == 0

Это довольно простой пример, но вполне актуальный. Здесь isEmpty — это вычислимое свойство (предполагается, что у класса, внутри которого находится функция, есть свойство size). Также для свойства можно задать и сеттер через set() = ..., и устанавливать значение можно будет через присваивание имя_свойства=значение.

var stringRepresentation: String
    get() = this.toString()
    set(value) {
        // Здесь мы можем сделать что-нибудь с value
    }

С одной стороны, это менее прозрачно, чем использование явных get/set-методов в стиле Java, однако это здорово разгружает код.

Более того, начиная с версии Kotlin 1.1 можно не прописывать тип свойства явно, если он может быть выведен автоматически:

val isEmpty get() = this.size == 0 // Имеет тип Boolean

Если нам нужно поменять только видимость или аннотировать get или set, то это довольно легко сделать с помощью указания области видимости или аннотации перед get или set:

var setterVisibility: String = "abc"
    private set // The setter is private and has the default implementation

var setterWithAnnotation: Any? = null
    @Inject set // Annotate the setter with Inject

В каком-то смысле в Kotlin нет полей, а есть только свойства, но опять же за деталями настоятельно рекомендую обратиться к источнику.

 

Интерполяция строк

Это просто, понятно и очень приятно:

val x = 10
val y = 20

println("x=$x y=$y")

 

Значения и вывод типов

Вместо модификатора final в языке Kotlin явным образом различаются константы и переменные через различные ключевые слова. Для объявления констант (значений) используется ключевое слово val, а для переменных — ключевое слово var. И снова это должно быть хорошо знакомо тем, кто программирует на Scala. Вообще, определение в Kotlin синтаксически решено иначе, чем в Java:

val x: Int = 10

Использование подобной конструкции дает большую свободу, потому что в языке присутствует механизм вывода типов и во многих случаях указание типа можно опустить.

val result = sequenceOf(10).map { it.toString() }.flatMap { it.toCharArray().asSequence() }.toList()

В данном примере компилятор самостоятельно выведет тип как List<Char>. Несмотря на все радости вывода типов, все-таки в сложных случаях я рекомендую прописывать тип явно, просто для того, чтобы получить ошибку компиляции как можно ближе к ее реальному источнику. Потому что, например, если в условном выражении типы для разн

anko Kotlin Dev

Kotlin: Как сделать меню панели инструментов с помощью Anko DSL?

Как сделать меню панели инструментов Android с Anko DSL прямо в классе пользовательского интерфейса? Не хотите писать слушателей в классе Activity. Что касается моего ответа, приведенного ниже, есть ли способ избежать XML-файла для описания элементов меню?

Как я могу отобразить свое представление anko без вызова overriding onCreate?

Это моя активность в LoginActivity . LoginActivityUI – это мой AnkoComponent для просмотра. @EActivity//not using R.layout.activity_login open class LoginActivity : BaseActivity() { //Anko view injection with dagger2 @Inject lateinit var ui: LoginActivityUI //Forced to do this and its not neat override fun onCreate(savedInstanceState: Bundle?) { super. onCreate(savedInstanceState) ui.setContentView(this) } @AfterViews fun afterView() { //Never called ui.setContentView(this) […]

Использование метода получения Anko Ошибка несоответствия AnkoContext <ViewGroup> Найдено AnkoContext <Context>

Я использую Anko в базовом приложении для Android, где я реализую recyclerView. В onCreateViewHolder() я получаю ошибку времени компиляции, onCreateViewHolder() тип Mismatch. Все остальное в коде ниже. class ListAdapter(val arrayList: ArrayList<String> = ArrayList<String>()) : RecyclerView.Adapter<Holder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder? { //type Mismatch error required AnkoContext<ViewGroup> Found AnkoContext<Context> return Holder(ItemUI().createView(AnkoContext.create(parent!!.context))) } override […]

Как сделать универсальный AppBar с Anko DSL?

Я пытаюсь создать панель инструментов, которую я могу вставить в другие компоненты Anko. Вот пример того, что я собираюсь: class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) MainUI().setContentView(this) val toolbar: Toolbar = find(R.id.toolbar) setSupportActionBar(toolbar) } } class MainUI : AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>) = with(ui) { coordinatorLayout { fitsSystemWindows = […]

Andoird anko DSL – добавление текстовых просмотров и создание их «новой строки», когда нет больше ширины экрана?

моя задача проста, у меня есть массив имен, каждое имя добавляется как отдельный текст. Однако некоторые из моих массивов длинны, а текстовые изображения слишком велики, чтобы поместиться на экране. Результат очень урод, и я не знаю, как его решить. Я попытался использовать все разные (насколько мне известно) типы макетов, и ни один из них, похоже, […]

Каков правильный способ использования расширений Anko Coroutines?

Поэтому я переношу пример приложения из RxJava в Kotlin / Anko Corontines, и мне интересно, если я делаю лучший (первый) подход к нему: fun getPopulationList() { val ref = asReference() async(UI) { try { ref(). setCurrentState(ViewState.State.LOADING) val background = bg { repository.populationResponse().execute().body() } ref().let { it.response = background.await() it.mvpView?.onGetData(it.response) it.setCurrentState(ViewState.State.FINISH) } } catch (e: Exception) { […]

Kotlin coroutines в Android: зачем использовать bg () из Anko вместо async ()?

Я начал использовать Kotlin coroutines на Android сегодня, и я заметил, что у Anko есть свой набор вспомогательных методов для них. Я понимаю, почему asReference() существует, но я не могу понять, почему работает bg() , учитывая, что в core coroutines lib уже есть async() . Код bg() довольно прост и использует async() внутри: @PublishedApi internal […]

Ошибка ввода типа. Ожидаемое несоответствие типа: требуется Строка найденная пара <String, String> в Котлине и Анко

Я создал базу данных с использованием библиотеки kotlin и kotlin . Я следую этой статье https://antonioleiva. com/databases-anko-kotlin/ Я пытаюсь вставить данные внутри блока базы данных, используя ниже, но я получаю сообщение об ошибке Ошибка ввода типа. Ожидаемое несоответствие типа: требуется Строка найденная пара fun insertPerson() { database.use { insert(PersonTable.Name, PersonTable.PersonName to «XX», PersonTable.Domain to «Technology», PersonTable.MobileNumber […]

Anko игнорирует layout_margin, определенный в стиле

Я создал собственный стиль: <style name=»Static»> <item name=»android:layout_width»>wrap_content</item> <item name=»android:layout_height»>wrap_content</item> <item name=»android:layout_marginEnd»>5dp</item> </style> Затем я расширил анко со статической функцией: inline fun ViewManager.static(theme: Int = R.style.Static, init: TextView.() -> Unit) = ankoView(::TextView, theme, init) Когда я использую это в своем макете: static { text = resources.getString(R.string.name) } Значение marginEnd игнорируется. Если я добавлю маржу вручную […]

Как использовать библиотеку Kotlin Anko в Android

В этом руководстве мы обсудим библиотеку Kotlin Anko. Мы узнаем, как использовать модуль Anko Commons в приложениях для Android.

Kotlin Anko Library

Anko — это библиотека Kotlin с открытым исходным кодом, разработанная JetBrains для революционного изменения в разработке Android. Это делает ваш код маленьким и с улучшенной читабельностью, он приближается к английской поэзии.

Anko был разработан с целью извлечь все преимущества синтаксиса Kotlin и сделать разработку под Android быстрее и проще.

Компоненты Anko

Библиотека Anko DSL состоит из следующих компонентов.

  • Anko Commons — Эта библиотека состоит из общих задач разработки Android. Он предоставляет помощники для намерений, ведения журнала, диалоговых окон предупреждений, асинхронности, всплывающих окон и т. Д.
  • Макеты Anko — Позволяет быстро и легко создавать макеты программным способом.
  • Anko SQLite — предоставляет вспомогательные функции для Android SQLite
  • Anko Coroutine — предоставляет служебные программы на основе kotlinx.библиотека сопрограмм .

В этом руководстве мы сосредоточимся на Anko Commons.

Модуль Anko Commons

Мы должны добавить следующую зависимость Gradle для использования модуля Anko Commons.

  реализация 'org.jetbrains.anko: anko-commons: 0.10.2'
  

Если вы хотите использовать стили Appcompat, добавьте следующую зависимость.

  реализация 'org.jetbrains.anko: anko-appcompat-v7-commons: 0.10.2'
  

Примеры Anko Commons

Мы реализуем следующие компоненты в нашем приложении для Android.

  • Тосты
  • Диалоги предупреждений
  • Селекторы
  • Намерения
  • Ведение журнала
  • Разные вспомогательные функции

Давайте рассмотрим каждую из вспомогательных функций утилиты по очереди.

1. Тосты

  val number = 1

тост ("Привет, Anko Commons")
тост (R.string.app_name)
longToast ("Номер $ длинного тоста")
  

Приведенный выше код создает вспомогательные функции для обычного тоста и длинного тоста с соответствующим временем как Toast.LENGTH_SHORT и тосты.LENGTH_LONG .

Их эквивалентный код, отличный от анко:

  Toast.makeText (applicationContext, "string", Toast.LENGTH_SHORT) .show ()
Toast.makeText (applicationContext, «строка», Toast.LENGTH_LONG) .show ()
  

Дополнительные сведения о тостах для Android, отличных от Anko, см. В этом руководстве.

2. Диалоги предупреждений

Функция утилиты Anko Commons для отображения диалогового окна предупреждения:

  предупреждение («У вас есть сообщение!», «Android Anko Alert») {
                yesButton {тост ("Да")}
                noButton {}
                нейтралитет ("Может быть") {}
            }. шоу()
  

Внутри блока предупреждений мы также можем добавить следующие свойства:

  • сообщение
  • заголовок
  • значок
  • positiveButton
  • negativeButton
  • okButton
  • cancelButton
  • onCancelled {}
  • customTitle {} — Здесь мы можем добавить макет Anko для макета заголовка. Мы рассмотрим это в следующем уроке.
  • customView {} — Здесь мы можем установить индивидуальный вид с помощью Anko Layouts. Подробнее об этом в следующем уроке.

Не-Anko код для диалоговых окон предупреждений:

  val builder = AlertDialog.Builder (this)
        
        с (строителем)
        {
            setTitle ("Androidly Alert")
            setMessage ("У нас есть сообщение")
            setPositiveButton ("ОК") {}
            setNegativeButton (android. R.string.no) {}
            setNeutralButton ("Может быть") {}
            шоу()
        }
  

3.Селекторы Commons

Синтаксис для добавления списка элементов в диалоговом окне предупреждений следующий:

  val languages ​​= listOf ("Java", "Python", "Kotlin", "Swift")
            селектор ("Ваш любимый язык программирования?", languages, {dialogInterface, i ->
                тост ("Ваш любимый язык - $ {languages ​​[i]}, верно?")
            })
  

Код диалога предупреждений Anko Commons более лаконичен, чем не-Anko коды, обсуждаемые здесь.

Эквивалентный общий код:

  val items = arrayOf («Красный», «Оранжевый», «Желтый», «Синий»)
        val builder = AlertDialog.Строитель (это)
        с (строителем)
        {
            setTitle ("Список элементов")
            setItems (items) {диалог, который ->
                Toast.makeText (applicationContext, items [которые] + "нажаты", Toast.LENGTH_SHORT) .show ()
            }

            setPositiveButton ("ОК", positiveButtonClick)
            шоу()
        }
  

4. Anko doAsync ()

Мы можем использовать служебную функцию doAsync () для запуска задачи в фоновом потоке и переключения обратно в основной поток.

  doAsync {
 // здесь реализуем фоновую задачу
   uiThread {
   // этот поток является основным потоком. обновите пользовательский интерфейс здесь.
   }
}
  

5. Android Anko Intents

Мы можем сократить наш код Intents, чтобы начать действия с использованием Anko Commons.

Ниже приведен не-Anko код для намерений в Android.

  val intent = Intent (this, SecondActivity :: class.java)
startActivity (намерение)
  

Код Anko Commons:

  startActivity  ()
  

Установка флагов и передача значений

Код Android:

  val intent = Intent (this, SecondActivity :: class.Ява)
intent.putExtra ("значение"; 3)
intent.putExtra ("имя", "Androidly")
intent.setFlag (Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity (намерение)
  

Код Anko:

  startActivity (intentFor  («значение» - 3, «имя» - «Androidly»).  SingleTop ())
  

Мы должны использовать намерение , чтобы передавал флаги.

6. Функции помощника по намерениям

  • makeCall (номер) — необходимо запрашивать разрешения времени выполнения. Мы поговорим об этом позже.
  • sendSMS (число,) — необходимо добавить разрешения на выполнение. Мы поговорим об этом позже.
  • просмотр (url: String) — необходимо установить разрешение на доступ в Интернет
  • общий доступ (текст, [тема])
  • электронная почта (электронная почта, [тема],)

Многие из них мы реализуем в нашем проекте Android Studio позже в этом руководстве.

7. Anko Logging

Anko commons предоставляет сокращенные формы для различных типов операторов регистрации.

Версия журнала отладки, отличная от Anko:

  Log.d ("ТЕГ", "отладка")
  

Мы должны реализовать интерфейс AnkoLogger в классе Activity. После этого вызовите функции регистрации, как показано ниже.

  информация («Информационный журнал»)
debug (5) // преобразуется в строку.
debug {"Каждый журнал может быть записан в любой из этих форм"}
warn (null) // показывает null
verbose {"Подробно"}
wtf ("Учебное пособие по Kotlin Androidly")
  

Обратите внимание, что существует два стиля вышеуказанных функций — () и {}

8. Разные функции

Вот некоторые из вспомогательных функций Anko Commons, которые используются для преобразования измерений:

  • dip () — преобразует переданное Int или float в dip
  • sp () — преобразует переданное Int или float в значение sp
  • px2dip () — преобразует px в dip
  • px2sp () — преобразует px в sp .

Пример структуры проекта Android Anko

Наше приложение для Android будет состоять из двух действий.

1. Код макета XML

Код макетов приведен ниже:

activity_main. xml

  


    <Кнопка
        android: id = "@ + id / btnShortToast"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Short Toast" />


    <Кнопка
        android: id = "@ + id / btnLongToast"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Длинный тост" />


    <Кнопка
        android: id = "@ + id / btnSimpleAlertDialog"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Простой диалог предупреждений" />


    <Кнопка
        android: id = "@ + id / btnAdvAlertDialog"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Расширенное диалоговое окно предупреждений" />


    <Кнопка
        android: id = "@ + id / btnAlertDialogWithList"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Диалоговое окно предупреждений со списком" />


    <Кнопка
        android: id = "@ + id / btnDoAsync"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "DO ASYNC" />


    <Кнопка
        android: id = "@ + id / btnIntent"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Перейти к следующему действию" />



  

активность_секунда. xml

  


    <Кнопка
        android: id = "@ + id / btnBrowseUrl"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Обзор URL" />


    <Кнопка
        android: id = "@ + id / btnSendEmail"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Отправить электронное письмо" />


    <Кнопка
        android: id = "@ + id / btnShare"
        android: layout_width = "wrap_content"
        android: layout_height = "wrap_content"
        android: text = "Поделиться" />



  

2. Код активности Kotlin

Код для MainActivity.kt приведен ниже.

  пакет net.androidly.androidlyankocommons

импортировать android.support.v7.app.AppCompatActivity
импортировать android.os.Bundle
импортировать android.support.v4.content.ContextCompat
импортировать android.support.v7.app.AlertDialog
импортировать kotlinx.android.synthetic.main.activity_main. *
import org.jetbrains.anko. *
импортировать org.jetbrains.anko.appcompat.v7.Appcompat

class MainActivity: AppCompatActivity (), AnkoLogger {

    переопределить веселье onCreate (savedInstanceState: Bundle?) {
        супер.onCreate (savedInstanceState)
        setContentView (R.layout.activity_main)


        info ("Информационный журнал")
        отладка (5)
        debug {"Каждый журнал может быть записан в любой из этих форм"}
        предупреждать (ноль)
        verbose {"Подробно"}
        wtf ("Учебное пособие по Kotlin Androidly")

        

        btnShortToast.setOnClickListener {
            тост ("Привет, Anko Commons")
            тост (R. string.app_name)
        }

        btnLongToast.setOnClickListener {
            longToast («Долго!»)
        }

        btnSimpleAlertDialog.setOnClickListener {
            alert («У вас есть сообщение!», «Android Anko Alert») {
                yesButton {тост ("Да")}
                noButton {}
                нейтралитет ("Может быть") {}
            }.шоу()
        }

        btnAdvAlertDialog.setOnClickListener {

            alert ("Обычное оповещение Anko") {
                title = "Заголовок"
                yesButton {тост ("Да")}
                noButton {}
                icon = ContextCompat.getDrawable (это @ MainActivity, R.mipmap.ic_launcher) !!
                onCancelled {
                    val dialog = alert (Appcompat) {
                        title = "Оповещения Anko"
                        message = "Не нажимайте за пределами диалога, чтобы снова отменить меня :)"
                        okButton {тост (android.R.string.ok)}

                    } .build ()

                    с (диалог)
                    {
                        шоу()
                        getButton (AlertDialog. BUTTON_POSITIVE) .setTextColor (ContextCompat.getColor (ctx, R.color.colorPrimary))
                    }
                }

            }.шоу()
        }


        btnAlertDialogWithList.setOnClickListener {

            val languages ​​= listOf ("Java", "Python", "Kotlin", "Swift")
            селектор ("Ваш любимый язык программирования?", languages, {dialogInterface, i ->
                тост ("Ваш любимый язык - $ {languages ​​[i]}, верно?")
            })
        }

        btnDoAsync.setOnClickListener {

            doAsync {

                Нить.сон (2000)

                uiThread {
                    тост («Эта работа сделана через 2 секунды»)
                }
            }
        }


        btnIntent.setOnClickListener {
            startActivity  (от «name» до «Androidly», от «age» до 1)
        }
    }
}
  

Внутри функции btnAdvAlertDialog мы создаем еще один диалог, когда диалог отменяется при касании снаружи.

Мы также по-другому реализовали диалоговое окно предупреждений. Мы получаем экземпляр AlertDialog и вносим изменения.

Код для SecondActivity.kt приведен ниже.

  пакет net.androidly.androidlyankocommons

импортировать android.support.v7.app.AppCompatActivity
импортировать android.os.Bundle
импортировать kotlinx.android.synthetic.main.activity_second. *
import org.jetbrains.anko.browse
импорт org.jetbrains.anko.email
import org.jetbrains.anko.share

class SecondActivity: AppCompatActivity () {

    переопределить веселье onCreate (savedInstanceState: Bundle?) {
        супер.onCreate (savedInstanceState)
        setContentView (R.layout.activity_second)


        btnBrowseUrl.setOnClickListener {
            просмотр ("https://www.androidly.net")
        }

        btnSendEmail.setOnClickListener {
            электронная почта ("[email protected] (mailto: [email protected])", "Проверить Androidly", "Текст сообщения из приложения Androidly")
        }



        btnShare.setOnClickListener {

            число val = 123
            поделиться ("Привет, $ номер", "Копировать")
        }
    }
}

  

Не забудьте добавить разрешение на доступ к Интернету в AndroidManifest.xml файл.

Вывод:

Создание пользовательского интерфейса с помощью Kotlin и Anko

С самого начала разработки Android работа с пользовательским интерфейсом была делом XML. Хотя теоретически пользовательский интерфейс можно было бы запрограммировать с использованием Java, от этого мало пользы. Не так давно JetBrains представила Kotlin, современный язык, ориентированный на JVM, который может служить этой цели для Android.

Jetbrains анонсировала Anko как более быстрый и простой стиль разработки для Android. Kotlin предлагает библиотеку Anko в качестве DSL (доменного языка) для разработки экрана Android.Быстрый пример:

Ниже приведен простой пользовательский интерфейс Android, состоящий из imageView и Button .

Вот его код Анко:

  verticalLayout {
        imageView (R.drawable.anko_logo).
                lparams (width = matchParent) {
                    обивка = погружение (20)
                    маржа = провал (15)
        }
        button ("Нажмите, чтобы поставить лайк") {
                onClick {тост ("Спасибо за любовь!")}
        }
    }
  

Здесь мы определили вертикальный линейный макет, который служит контейнером для изображения и кнопки .Расположение видов в макете было определено с помощью lparams () . И то, что происходит при нажатии кнопки, также определяется внутри определения пользовательского интерфейса благодаря встроенной функции Kotlin.

Преимущества использования Anko
  • Мы можем встраивать макеты пользовательского интерфейса в исходный код, тем самым делая его типобезопасным.
  • Поскольку мы пишем не в XML, это повышает эффективность, так как нет необходимости тратить время процессора на синтаксический анализ XML.
  • После программного преобразования пользовательского интерфейса мы можем поместить фрагмент Anko DSL в функцию.Таким образом упрощается повторное использование кода.
  • И ясно, что код стал более лаконичным, читаемым и понятным.

А теперь давайте создадим приложение, в котором перечислены задачи с помощью Anko Layout и Kotlin.

Вы можете найти репозиторий этого приложения To-do на GitHub

Добавление библиотеки Anko в Android Studio

Взгляните на Оптимизацию кода Java для Android с помощью Kotlin, чтобы узнать, как добавить Kotlin в свой проект Android. Наряду с Kotlin нам нужно добавить зависимости Anko в app / build.gradle , чтобы мы могли скомпилировать проект:

  скомпилировать org.jetbrains.anko: anko-sdk15: 0.8.3
// sdk19, 21 и 23 также доступны
  

Эта зависимость может быть добавлена ​​в зависимости от того, на какую minSdkVersion вы нацеливаете свое приложение. В приведенном выше примере показано, что он нацелен на 15 <= minSdkVersion <19. Вы можете проверить, какие другие библиотеки Anko доступны, которые могут вам понадобиться, в репозитории Anko GitHub.
Мы также будем использовать следующие библиотеки:

  compile 'org.jetbrains.anko: анко-дизайн: 0.8.3 '
скомпилировать 'org.jetbrains.anko: anko-appcompat-v7: 0.8.3'
  

Вызов макета Anko в действии

Мы больше не пишем XML-макеты, поэтому нам не нужно ни вызывать XML-представления, ни использовать findViewById () метод. Предположим, что наш класс пользовательского интерфейса Anko — MainUI , тогда мы можем установить содержимое нашей деятельности с помощью MainUI как:

  var ui = MainUI () // Класс MainUI заменяет макет XML
ui.setContentView (this) // это относится к классу Activity
  

Теперь создайте новый файл Kotlin MainActivity.kt и добавьте к нему следующий код:

  импорт android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import org.jetbrains.anko. *;
импорт java.util. *

class MainActivity: AppCompatActivity () {

    val task_list = ArrayList  () // список, состоящий из задач

    переопределить веселье onCreate (savedInstanceState: Bundle?) {
        super.onCreate (savedInstanceState)
        saveInstanceState? .let {
            val arrayList = savedInstanceState.get ("ToDoList")
            список заданий.addAll (arrayList как список )
        }
        var adapter = TodoAdapter (task_list) // определить адаптер
        var ui = MainUI (адаптер) // определяем макет пользовательского интерфейса Anko, который будет использоваться
        ui.setContentView (this) // Установите пользовательский интерфейс Anko для этого действия

    }
    переопределить веселье onSaveInstanceState (outState: Bundle?) {
        outState? .putStringArrayList ("ToDoList", список_задач)
        super.onSaveInstanceState (outState)
    }
}
  

task_list — это ArrayList , который будет заполнять TodoAdapter Listview в нашем приложении to-do. MainUI (адаптер) — это наш файл пользовательского интерфейса Anko, который принимает в качестве аргумента адаптер класса TodoAdapter . Итак, давайте теперь создадим класс TodoAdapter .

Строительный адаптер для ListView

Класс TodoAdapter имеет поле члена list типа ArrayList и расширяет BaseAdapter . Итак, нам нужно переопределить следующие 4 функции-члены:

  общедоступный int getCount ()
публичный объект getItem (int i)
public long getItemId (int i)
общедоступный View getView (int i, View view, ViewGroup viewGroup)
  

В методе getView () мы разработаем макет элемента списка с помощью Anko.

  переопределить удовольствие getView (i: Int, v: View ?, parent: ViewGroup?): View {
    вернуться с помощью (родительский !!. контекст) {
        // taskNum будет служить S.No. списка начиная с 1
        var taskNum: Int = i +1

        // Макет для элемента представления списка
        linearLayout {
            lparams (ширина = matchParent, высота = wrapContent)
            обивка = погружение (10)
            ориентация = ГОРИЗОНТАЛЬНО

            // Номер задачи
            textView {
                id = R.id.taskNum
                text = "" + taskNum
                textSize = 16f
                typeface = Гарнитура.МОНОКОСМИЧЕСКОЕ
                обивка = погружение (5)
            }

            // Название задачи
            textView {
                id = R.id.taskName
                текст = list.get (я)
                textSize = 16f
                typeface = DEFAULT_BOLD
                обивка = погружение (5)
            }
        }
    }
}
  
  • В этой функции мы возвращаем представление, содержащее элемент списка, который является макетом horizontalListView . Это достигается с помощью Kotlin с синтаксисом , который позволяет нам одновременно вызывать множество методов для экземпляра объекта.
  • Каждый элемент списка содержит два текстовых окна для отображения номера задачи и имени задачи.
  • linearLayout , textView — это функции расширения. Расширения дают нам возможность включить любой класс с новой функциональностью.
  • текст , textSize , шрифт имеют методы получения и установки, определенные в классе android.widget.TextView . padding — это свойство расширения, определенное в Anko.

Двигаясь вперед, нам нужно определить функции управления списком. Итак, у нас есть функции add (String), и delete (Int) в классе TodoAdapter . add (String) принимает имя задачи, которую нужно добавить, в качестве аргумента. Положение элемента служит аргументом в функции delete (Int) , как показано ниже:

  // функция для добавления элемента в список
fun add (text: String) {
    list.add (list.size, текст)
    notifyDataSetChanged () // обновляет базовый набор данных
}

// функция для удаления элемента из списка
fun delete (i: Int) {
    список.removeAt (я)
    notifyDataSetChanged () // обновляет базовый набор данных
}
  

Итак, теперь мы разработали список и можем добавлять и удалять элементы в наш список. Это завершает код для этого класса адаптера:

  импорт android.graphics.Typeface
импортировать android.graphics.Typeface.DEFAULT_BOLD
импортировать android.view.View
импортировать android.view.ViewGroup
импортировать android.widget.BaseAdapter
импортировать android.widget.LinearLayout.HORIZONTAL
импорт org.jetbrains.anko.*
импорт java.util. *

class TodoAdapter (список значений: ArrayList  = ArrayList  ()): BaseAdapter () {
    переопределить удовольствие getView (i: Int, v: View ?, parent: ViewGroup?): View {
        вернуться с помощью (родительский !!. контекст) {
            // taskNum будет служить S.No. списка начиная с 1
            var taskNum: Int = i +1

            // Макет для элемента представления списка
            linearLayout {
                id = R.id.listItemContainer
                lparams (ширина = matchParent, высота = wrapContent)
                обивка = погружение (10)
                ориентация = ГОРИЗОНТАЛЬНО

                textView {
                    id = R.id.taskNum
                    text = "" + taskNum
                    textSize = 16f
                    typeface = Гарнитура.MONOSPACE
                    обивка = погружение (5)
                }

                textView {
                    id = R.id.taskName
                    текст = list.get (я)
                    textSize = 16f
                    typeface = DEFAULT_BOLD
                    обивка = погружение (5)
                }
            }
        }
    }

    переопределить удовольствие getItem (position: Int): String {
        список возврата [позиция]
    }

    переопределить удовольствие getCount (): Int {
        список возврата.размер
    }

    переопределить удовольствие getItemId (position: Int): Long {
        // может использоваться для возврата столбца идентификатора элемента таблицы
        возврат 0L
    }

    // функция для добавления элемента в список
    fun add (text: String) {
        list.add (list.size, текст)
        notifyDataSetChanged ()
    }

    // функция для удаления элемента из списка
    fun delete (i: Int) {
        list.removeAt (я)
        notifyDataSetChanged ()
    }

}
  

Обратите внимание, что мы должны импортировать org.jetbrains.anko.* для использования Anko DSL в наших файлах классов.

Создание экрана списка дел

Anko предоставляет нам удобство использования пользовательского интерфейса для Activity в отдельном классе Kotlin. Таким образом, каждый экран можно рассматривать как пару классов Kotlin UI-Activity. Этот класс пользовательского интерфейса разработан путем расширения возможностей интерфейса AnkoComponent , определенного в пакете org.jetbrains.anko . Наряду с этим интерфейсом JetBrains бесплатно предлагает функцию предварительного просмотра макета DSL.Так выглядит предварительный просмотр макета Anko DSL в Android Studio:

(Источник: blog.jetbrains.com)

Соответствующий плагин для Anko Preview можно скачать здесь. Обратите внимание, что на момент написания этой статьи Anko DSL Preview для Android Studio 2.2 была указана как открытая проблема.
Возвращаясь к To-do-App, теперь мы спроектируем класс MainUI , который содержит список всех задач. MainUI Класс расширяет интерфейс AnkoComponent , где T относится к владельцу пользовательского интерфейса i.е. действие, содержимым которого будет этот пользовательский интерфейс. В нашем случае владельцем является MainActivity , который мы уже определили выше. Затем во время инициализации мы должны передать объект TodAadapter этому классу, поскольку этот адаптер будет использоваться для заполнения списка. Итак, объявление класса MainUI становится:

  класс MainUI (val todoAdapter: TodoAdapter): AnkoComponent 
  

Теперь нам нужно переопределить функцию createView () , которая будет принимать объект AnkoContext в качестве аргумента и возвращать тип View :

  переопределить удовольствие createView (ui: AnkoContext ): View = with (ui) {}
  

Определение пользовательского интерфейса, которое мы предоставляем внутри функции createView () , возвращается в действие владельца, которым в данном случае является MainActivity .Итак, приступим к написанию кода метода createView () .

Шаг 1. Создание главного экрана

Изначально на главном экране пустой список задач. Итак, у нас есть textView , который просит пользователя создать список задач на день:

  return relativeLayout {
        // объявление ListView
        var todoList: ListView? = ноль

        // textView отображается, когда нет задачи
        val hintListView = textView ("Какой у вас список задач на сегодня?") {
            textSize = 20f
        }.lparams {
            centerInParent ()
        }
}
  

centerInParent () — это вспомогательный метод для определения компоновки представления относительно центра по вертикали и горизонтали.
Поскольку это приложение для задач, его суть заключается в списке, отображающем задачи. Итак, здесь мы определяем наш listView :

  // listView
verticalLayout {
    todoList = listView {
    // назначаем адаптер
        адаптер = todoAdapter
        }
} .lparams {
        маржа = провал (5)
}
  

todoAdapter — это переменная-член класса MainUI , который мы определили в объявлении класса.Мы инициируем адаптер из listView со значением todoAdapter , который является объектом класса TodoAdpater , и заполняем список.
Чтобы помочь пользователю в добавлении задачи, мы предоставили FloatingActionButton в правом нижнем углу главного экрана, следуя принципам Material design . Итак, в Anko мы программируем FLOATINGActionButton как:

  FloatingActionButton {
            imageResource = android.R.drawable.ic_input_add
        } .lparams {
            // установка кнопки в нижнем правом углу экрана
            маржа = провал (10)
            alignParentBottom ()
            alignParentEnd ()
            alignParentRight ()
            gravity = Gravity.BOTTOM или Gravity.END
        }
  
Шаг 2. Отображение диалогового окна предупреждения AddTask

Anko обеспечивает простой способ установки onClickListener для View . Итак, мы можем добавить onClickListener к floatActionButton , добавив внутри него метод onClick () .Давайте создадим настраиваемое диалоговое окно, появляющееся при щелчке мышью на кнопке floatActionButton , в котором пользователю будет предложено ввести задачу и добавить ее в список:

  FloatingActionButton {
            imageResource = android.R.drawable.ic_input_add
            по щелчку {
                val adapter = todoList? .adapter как TodoAdapter
                alert {
                    customView {
                        verticalLayout {
                        // Заголовок диалога
                            панель инструментов {
                                id = R.id.dialog_toolbar
                                lparams (ширина = matchParent, высота = wrapContent)
                                backgroundColor = ContextCompat.getColor (ctx, R.color.colorAccent)
                                title = "Какая у вас следующая веха?"
                                setTitleTextColor (ContextCompat.getColor (ctx, android.R.color.white))
                            }
                            val task = editText {
                                hint = "Сделать задание"
                                обивка = погружение (20)
                            }
                            PositiveButton ("Добавить") {
                                если (задача.text.toString (). isEmpty ()) {
                                    тост ("Упс !! Ваша задача ничего не говорит!")
                                }
                                else {
                                    адаптер.add (task.text.toString ())
                                    showHideHintListView (todoList !!)
                                }
                            }
                        }
                    }
                }.шоу()
            }
        } .lparams {
            // установка кнопки в нижнем правом углу экрана
            маржа = провал (10)
            alignParentBottom ()
            alignParentEnd ()
            alignParentRight ()
            gravity = Гравитация.BOTTOM или Gravity.END
        }
  
  • alert {} — это встроенная функция для создания диалогового окна Anko. По умолчанию в диалоговом окне Anko мы можем установить текстовое сообщение и предоставить postiveButton и negativeButton . Мы можем настроить диалоговое окно предупреждения с помощью customView .
  • verticalLayout — это linearLayout с вертикальной ориентацией.
  • Мы добавили заголовок в диалог с помощью панели инструментов , таким образом настроив его.Обратите внимание, как мы назначаем цвет представлению в диалоговом окне: backgroundColor = ContextCompat.getColor (ctx, R.color.colorAccent)
    Здесь ctx относится к Context , определенному в классе AlertDialogBuilder в классе package org.jetbrains.anko , который нам нужно передать в качестве аргумента, чтобы Android знал контекст, на который мы ссылаемся.
  • postiveButton () — это метод Anko Helper, который позволяет нам определять, что происходит, когда пользователь отправляет диалог.Здесь мы проверяем, не пуста ли задача , затем мы добавляем задачу в адаптер списка с помощью метода add , который мы определили в классе TodoAdapter .
  • Что такое showHideHintListView (todoList !!) ? Что ж, это метод, который мы определили, чтобы скрыть textView hintListView , который появляется на главном экране, чтобы освободить место для нашего списка. Когда listView пуст, мы показываем hintListView , иначе мы его скрываем.

    // функция для отображения или скрытия над textView
    fun showHideHintListView (listView: ListView) {
    if (getTotalListItems (listView)> 0) {
    hintListView.visibility = View.GONE
    } else {
    hintListView.visibility = View.VISIBLE
    }
    }

Здесь getTotalListItems (listView) — это метод-член класса MainUI , который возвращает количество элементов в переданном listView . Это обычная функция Котлина:

  // функция для получения общего количества элементов в списке
весело getTotalListItems (список: ListView?) = список ?.адаптер? .count?: 0
  

Наконец, нажав на FLOATINGActionButton , мы видим диалог:

И как только мы добавим несколько задач, мы увидим список задач:

Шаг 3 — Удаление задачи

Помните, что мы определили метод delete (Int) в классе TodoAdapter , который удаляет элемент из списка. Пришло время разработать пользовательский интерфейс, который, в свою очередь, будет вызывать этот метод
. Следуя шаблонам проектирования Android, мы можем отображать параметры задачи при нажатии и удержании задачи.Итак, давайте определим, что происходит onLongClick с элементом списка. Вернитесь к определению listView и добавьте следующее:

  onItemLongClick {adapterView, view, i, l ->
val options = listOf ("Удалить")
    селектор ("Параметры задачи", параметры) {j ->
            var task = adapter.getItem (i)
            todoAdapter? .delete (я)
            // проверяем, пуст ли список, затем показываем подсказку
            showHideHintListView (это @ listView)
            longToast («Задача $ {задача} удалена»)
    }
    правда
}
  
  • Здесь todoAdapter — объект класса TodoAdapter .Вызов метода удаления на адаптере дает сообщение об ошибке, в котором говорится, что к тому времени он мог измениться. Итак, мы должны вызвать метод delete на todoAdapter . Другой вариант — привести тип адаптера к TodoAdapter . И способ kotlin сделать это:
    (адаптер как TodoAdapter) ?. delete (i)
    i относится к позиции элемента, по которому выполняется щелчок.
  • Селектор — это своего рода диалоговое окно Anko , которое дает нам возможность определять список элементов, на которые можно нажимать.Здесь мы выбрали только один вариант - Удалить. Мы можем предоставить пользователю другие варианты на выбор. Ниже пример:
  verticalLayout {
    todoList = listView {
        адаптер = todoAdapter
        onItemLongClick {adapterView, view, i, l ->
            val options = listOf ("Завершено", "Выполняется", "Не начато", "Удалить")
            селектор ("Параметры задачи", параметры) {j ->
                if (j == 3) {
                    var task = adapter.getItem (i)
                    todoAdapter ?.удалить (я)
                    showHideHintListView (это @ listView)
                    longToast («Задача $ {задача} удалена»)
                } else {
                    longToast ("Задача $ {adapter.getItem (i) .toString ()} была помечена как \" $ {options [j]} \ "")
                }
            }
            правда
        }
    }
} .lparams {
        маржа = провал (5)
}
  

Обновление базы данных, уведомление пользователя или любой другой код может быть выполнен вместо тоста, чтобы расширить функциональность приложения To-do.Так выглядит диалог selecter на экране:

Таким образом, полный код для класса MainUI :

  импорт android.support.v4.content.ContextCompat
импортировать android.view.Gravity
импортировать android.view.View
импортировать android.widget.FrameLayout
импортировать android.widget.ListView
import org.jetbrains.anko. *
импортировать org.jetbrains.anko.appcompat.v7.toolbar
import org.jetbrains.anko.design.floatingActionButton

class MainUI (val todoAdapter: TodoAdapter): AnkoComponent  {
    переопределить удовольствие createView (ui: AnkoContext ): View = with (ui) {
        return relativeLayout {
            var todoList: ListView? = ноль

            // textView отображается, когда нет задачи
            val hintListView = textView ("Какой у вас список задач на сегодня?") {
                textSize = 20f
            }.lparams {
                centerInParent ()
            }

            // функция для отображения или скрытия над textView
            fun showHideHintListView (listView: ListView) {
                if (getTotalListItems (listView)> 0) {
                    hintListView.visibility = View.GONE
                } else {
                    hintListView.visibility = View.VISIBLE
                }
            }

            // макет для отображения ListView
            verticalLayout {
                todoList = listView {
                    адаптер = todoAdapter
                    onItemLongClick {adapterView, view, i, l ->
                        val options = listOf ("Завершено", "Выполняется", "Не начато", "Удалить")
                        селектор ("Параметры задачи", параметры) {j ->
                            if (j == 3) {
                                var task = адаптер.getItem (я)
                                todoAdapter? .delete (я)
                                showHideHintListView (это @ listView)
                                longToast («Задача $ {задача} удалена»)
                            } else {
                                longToast ("Задача $ {adapter.getItem (i) .toString ()} была помечена как \" $ {options [j]} \ "")
                            }
                        }
                        правда
                    }
                }
            }.lparams {
                    маржа = провал (5)
            }

            // Добавляем задачу FloatingActionButton справа внизу
            FloatingActionButton {
                imageResource = android.R.drawable.ic_input_add
                по щелчку {
                    val adapter = todoList? .adapter как TodoAdapter
                    alert {
                        customView {
                            verticalLayout {
                                панель инструментов {
                                    id = R.id.dialog_toolbar
                                    lparams (ширина = matchParent, высота = wrapContent)
                                    backgroundColor = ContextCompat.getColor (ctx, R.color.colorAccent)
                                    title = "Какая у вас следующая веха?"
                                    setTitleTextColor (ContextCompat.getColor (ctx, android.R.color.white))
                                }
                                val task = editText {
                                    hint = "Сделать задание"
                                    обивка = погружение (20)
                                }
                                PositiveButton ("Добавить") {
                                    если (задача.text.toString (). isEmpty ()) {
                                        тост ("Упс !! Ваша задача ничего не говорит!")
                                    }
                                    else {
                                        адаптер.add (task.text.toString ())
                                        showHideHintListView (todoList !!)
                                    }
                                }
                            }
                        }
                    }.шоу()
                }
            }.lparams {
                // установка кнопки в нижнем правом углу экрана
                маржа = провал (10)
                alignParentBottom ()
                alignParentEnd ()
                alignParentRight ()
                gravity = Gravity.BOTTOM или Gravity.END
            }
        }.применять {
            layoutParams = FrameLayout.LayoutParams (matchParent, matchParent)
                    .применять {
                        leftMargin = падение (5)
                        rightMargin = падение (5)
                    }
        }

    }

    // функция для получения общего количества элементов в списке
    весело getTotalListItems (список: ListView?) = список ?.адаптер? .count?: 0
}
  

Последние мысли

Мы не использовали какие-либо ресурсы макета XML при разработке этого приложения To-do, но мы можем разработать приложение в аналогичном стиле. Anko снимает бремя представления данных, реагирования на взаимодействие с пользователем, подключения к базам данных и многого другого из действий или фрагментов в приложении. Кроме того, изоляция классов UI и Activity приближает приложение к архитектуре MVP (Model-View-Presenter). Вы можете узнать о расширенных функциях Anko здесь.
Несмотря на то, что у него есть несколько недостатков, таких как более медленная компиляция и большой размер приложения, он дает отличные возможности для повторного использования, поддержки и тестирования кода. Таким образом, Kotlin-Anko готов к работе с производственными приложениями Android.

Сообщите мне свое мнение об Анко в разделе комментариев.

представляет Anko для Android - блог Kotlin

Мы рады объявить о библиотеке, над которой мы работаем для разработки Android, которая, среди прочего, позволяет создавать интерфейсы приложений безопасным по типу и динамическим способом с использованием DSL.

Образец вкуса

Вот небольшой пример, описывающий некоторые возможности Anko. Представьте, что нам нужно создать простую форму регистрации, состоящую из EditText для имени пользователя и кнопки «Зарегистрироваться» . Код для этого с использованием Anko будет:

 импорт kotlinx.android.anko. *

class MainActivity: Activity () {

    переопределить веселье onCreate (savedInstanceState: Bundle?) {
        super.onCreate (savedInstanceState)

        verticalLayout {
            обивка = погружение (16)
            textView ("Имя пользователя:") {
                textSize = 18f
            }.layoutParams {verticalMargin = dip (4)}

            val логин = editText ()

            button ("Зарегистрироваться") {
                textSize = 20f
                onClick {логин (login.text)}
            } .layoutParams {topMargin = dip (8)}
        }
    }
} 

Anko широко использует функции расширения и свойства Kotlin, организованные в типобезопасные конструкторы для описания пользовательского интерфейса. В свою очередь, мы получаем краткость и безопасность типов во время компиляции.

Конечно, мы также можем увидеть предварительный просмотр во время разработки, используя плагин Anko Preview, доступный как для IntelliJ IDEA, так и для Android Studio:

Если мы теперь хотим добавить еще один виджет ввода текста, например электронное письмо, мы, вероятно, могли бы создать еще одну пару вызовов функций textView () и editText () .Однако более удачным подходом было бы извлечь соответствующий фрагмент DSL в новую функцию:

 переопределить удовольствие onCreate (savedInstanceState: Bundle?) {
    super.onCreate (savedInstanceState)

    verticalLayout {
        обивка = погружение (16)
        val login = inputField ("Имя пользователя")
        val email = inputField ("Электронная почта")

        button ("Зарегистрироваться") {
            textSize = 20f
            onClick {логин (login.text)}
        } .layoutParams {topMargin = dip (8)}
    }
}

весело _LinearLayout.inputField (name: String): TextView {
    textView ("$ name:") {
        textSize = 18f
    } .layoutParams {verticalMargin = dip (4)}
    вернуть editText ()
} 

Для любых дополнительных входов требуется только один вызов функции.

Конечный результат формы будет:

Частично определенные слушатели

Anko очень полезен, когда вы используете прослушиватели Android с большим количеством методов. Рассмотрим следующий код, написанный без использования Anko:

 seekBar.setOnSeekBarChangeListener (объект: OnSeekBarChangeListener {
  переопределить удовольствие onProgressChanged (seekBar: SeekBar, progress: Int, fromUser: Boolean) {
    // Что нибудь
  }
  переопределить веселье onStartTrackingTouch (seekBar: SeekBar?) {
    // Просто пустой метод
  }
  переопределить удовольствие onStopTrackingTouch (seekBar: SeekBar) {
    // Еще один пустой метод
  }
}) 

Вот версия с использованием Anko:

 seekBar {
  onProgressChanged {(seekBar, прогресс, fromUser) ->
    // Что нибудь
  }
} 

Методы с пустыми телами больше не требуют пустых реализаций.Кроме того, если установить onProgressChanged () и onStartTrackingTouch () для одного и того же представления, эти два «частично определенных» слушателя будут объединены.

Больше, чем DSL

Anko - это не просто DSL, а библиотека, которая упрощает разработку Android в различных областях. Он имеет множество методов, охватывающих диалоги, асинхронные задачи, службы, намерения и даже доступ к базе данных SQLite.

Например, если вы хотите начать новое действие :

 // Без Анко
val intent = Intent (this, javaClass  ())
намерение.putExtra ("идентификатор"; 5)
startActivity (намерение)

// С Анко
startActivity  (от "id" до 5) 

Или активируйте вибратор:

 // Без Анко
val vibrator = getSystemService (Context.VIBRATOR_SERVICE) как вибратор
вибратор. вибратор (500)

// С Анко
вибратор. вибратор (500) 

Или даже отправьте тост:

 // Без Анко
Toast.makeText (это, «Загрузка завершена!», Toast.LENGTH_SHORT) .show ()

// С Анко
тост («Загрузка завершена!») 

Поддержка существующего кода

Вы можете оставить свои старые классы написанными на Java.Более того, если вы все еще хотите (или имеете) написать класс активности Kotlin и по какой-то причине раздуть XML-макет, вы можете использовать свойства View и помощники слушателей, которые упростят задачу:

 name.hint = "Введите свое имя"
name.onClick {/ * сделать что-нибудь * /} 

Преимущества Anko

Надеюсь, вы видите, что Anko предлагает ряд преимуществ, в частности:

  • Все в одном месте . Вместо того, чтобы разделять макеты на статические (XML) и динамические части, а затем пытаться связать их вместе, мы можем просто написать все, что захотим, с помощью Kotlin. Проверка типов во время компиляции - приятный бонус.
  • Anko может сделать наш код более лаконичным и читаемым .
  • Позволяет легко использовать повторно . Мы можем просто извлечь часть DSL в функцию и использовать ее несколько раз.

Попробуйте!

Anko все еще находится в стадии альфа-тестирования, но мы хотим выпустить его раньше, чтобы получить ваши отзывы, поэтому, пожалуйста, попробуйте. Мы сделали это настолько простым, насколько это возможно. Все это опубликовано в Maven Central, и если вы используете Gradle, вы можете легко добавить необходимые зависимости в сборку .gradle файл:

 dependencies {
  скомпилировать 'org.jetbrains.anko: anko: 0.5-15'
} 

Плагин Anko Preview доступен как для IntelliJ IDEA, так и для Android Studio. Вы можете скачать его прямо из репозитория плагинов.

Существуют двоичные файлы, предназначенные как для необработанного Android (SDK версии 15, Ice Cream Sandwich), так и для Android с пакетом support-v4.

И последнее, но не менее важное: как и все, что связано с Kotlin, Anko является полностью открытым исходным кодом. Репозиторий находится на GitHub, и, как всегда, мы приветствуем участие!

Расширенные возможности Anko - блог Kotlin

На прошлой неделе мы опубликовали новую версию Anko.Хотя основной целью этой библиотеки является создание макетов через DSL, даже пользователи XML-макетов могут извлечь из этого пользу. Сегодня мы поговорим о таких «амбивалентных» особенностях Anko.

Помощники по намерениям

Обычный способ запуска нового действия Activity - создать намерение , возможно, ввести в него некоторые параметры и, наконец, передать созданное намерение методу startActivity () контекста Context .

 val intent = Intent (this, javaClass  ())
намерение.putExtra ("идентификатор"; 5)
intent.putExtra ("имя", "Джон")
startActivity (намерение) 

С Anko мы можем сделать это ровно в одной строке кода:

 startActivity  (от "id" до 5, от "name" до "John") 

startActivity () Функция принимает пары ключ-значение, которые будут переданы как дополнительные параметры Intent . Также доступна другая функция startActivityForResult () с аналогичной семантикой.

Пожалуйста, обратитесь к разделу справки по функциям Intent Builder для получения дополнительной информации.

Популярные сокращения

Почти в каждом приложении есть код, который загружает страницу в веб-браузере по умолчанию или открывает новый экран электронной почты с использованием намерений Android, поэтому в Anko есть вспомогательные функции:

 обзор ("http://somewebsite.org (http://somewebsite.org/)")
email ("[email protected] (mailto: [email protected])", "Я здесь!", "Текст сообщения") 

Другие полезные намерения описаны в справочном разделе «Полезные вызывающие намерения».

Диалоги предупреждений

Anko предоставляет декларативный способ создания диалоговых окон предупреждений с текстовыми сообщениями, списками, индикаторами выполнения и даже с вашим собственным макетом DSL.

Для простого текстового оповещения с парой кнопок внизу все, что вам нужно, это:

 alert ("Заказать", "Вы хотите заказать этот товар?") {
    PositiveButton ("Да") {processAnOrder ()}
    negativeButton ("Нет") {}
} .show () 

Есть функция, которая создает и показывает диалог списка:

 val flowers = listOf («Хризантема», «Роза», «Гиацинт»)
selector ("Какой ваш любимый цветок?", flowers) {i ->
    тост ("Итак, ваш любимый цветок - $ {flowers [i]}, верно?")
} 

Поддерживаются как неопределенные, так и базовые диалоговые окна прогресса:

 progressDialog ("Подождите минутку."," Скачивание… ")
indeterminateProgressDialog («Получение данных…») 

Кроме того, как упоминалось выше, вы можете использовать DSL Anko в диалогах для создания собственного макета:

 alert {
    customView {
        verticalLayout {
            val familyName = editText {
                hint = "Фамилия"
            }
            val firstName = editText {
                hint = "Имя"
             }
             PositiveButton ("Зарегистрироваться") {register (familyName.text, firstName.text)}
         }
    }
}.показать () 

Услуги

Системные службы

Android, такие как WifiManager , LocationManager или Vibrator , доступны в Anko через свойства расширения для контекста :

 if (! WifiManager.isWifiEnabled ()) {
    вибратор. вибратор (200)
    тост ("Wi-Fi отключен. Пожалуйста, включите!")
} 

Асинхронные задачи

Вероятно, самый популярный способ выполнения кода в фоновом режиме - создать подкласс AsyncTask .Но, несмотря на свою популярность, во многих отношениях неудобен. В Anko есть несколько функций, которые практически выполняют те же функции, но их проще использовать.

async () {...} Функция выполняет код внутри {} под ThreadExecutor . Вы можете использовать значение по умолчанию или передать свое.

 async (someExecutor) {// опускаем параметр, чтобы использовать исполнителя по умолчанию
// Этот код будет выполняться в фоновом режиме
} 

Если вы хотите вернуться к потоку пользовательского интерфейса внутри async () , вы можете использовать функцию uiThread () .

 async {
    // Поработай немного
    uiThread {
        тост («Работа сделана!»)
    }
} 

uiThread () имеет особую семантику внутри async () : async () не содержит экземпляра Context , а только WeakReference к нему, поэтому, даже если выполнение лямбда никогда не завершается, контекст Экземпляр не протечет.

 async {
    uiThread {
        / * Безопасная версия. Этот код не будет выполнен
            если базовый контекст отсутствует.* /
    }
    ctx.uiThread {
    / * Здесь мы вызываем `uiThread`
        функция расширения для контекста напрямую,
        поэтому мы держим ссылку на него. * /
    }
} 

Лесозаготовка

Android SDK предоставляет класс android.util.Log , который состоит из нескольких методов ведения журнала. Использование простое, но методы требуют передачи аргумента тега, а фактическое сообщение журнала должно быть String . Вы можете избавиться от этого, используя свойство AnkoLogger :

 class SomeActivity: Activity (), AnkoLogger {
    fun someMethod () {
        info («Информационное сообщение»)
        отладка (42) //.Метод toString () будет вызываться автоматически
    }
} 

Имя тега по умолчанию - это имя класса (в данном случае SomeActivity ), но вы можете легко изменить его, переопределив свойство loggerTag для AnkoLogger .

У каждого метода есть две версии: простой и «ленивый» (лямбда будет выполняться, только если Log.isLoggable (tag, Log.INFO) равно true ).

 info ("строка" + "конкатенация")
info {"Строка" + "конкатенация"} 

Подробнее о ведении журнала можно прочитать в разделе «Справка по ведению журнала».

Заключение

Чтобы попробовать Anko , следуйте этим инструкциям.

И, как обычно, мы будем рады вашим отзывам.

Выпущен

Anko 0.6 - Kotlin Blog

Сегодня мы рады представить новую версию Anko - библиотеки, которая упрощает разработку приложений для Android. Мы рады получить много отзывов, и некоторые изменения в версии 0.6 были фактически предложены сообществом.

ПРЕДУПРЕЖДЕНИЕ: имя пакета изменено

Что ж, извините. По историческим причинам имя пакета Anko раньше было kotlinx.android.anko , и мы изменили его на org.jetbrains.anko в версии 0.6, чтобы соответствовать имени артефакта Maven.

Новые слушатели

Anko 0.5 представил частично определенные слушатели, которые уменьшают многословность кода: когда нам нужно определить только один метод многометодного слушателя, нам не нужно реализовывать методы, которые нам не нужны.На основании ваших отзывов (спасибо, SalomonBrys!) Эта функция была переработана в версии 0.6:

.

  • Частично определенные слушатели теперь могут использоваться как вне схем DSL, так и внутри;
  • Синтаксис легче понять;
  • Логика «под капотом» проще.

Вот как это выглядит сейчас:

 editText {
    textChangedListener {
        onTextChanged {текст, начало, до, количество ->
            тост ("Новый текст: $ text")
        }
    }
} 

Квалификаторы конфигурации

Квалификаторы

используются для поддержки разных макетов для разных устройств, регионов и т. Д.

DSL Anko теперь поддерживает функцию configuration () , которая определяет квалификаторы, для которых предназначен макет:

Конфигурация

 (screenSize = ScreenSize.LARGE, ориентация = Orientation.LANDSCAPE) {
    / *
      Этот код будет только выполняться
      если экран большой и его ориентация - альбомная
    * /
} 

Этот код эквивалентен размещению вашего XML-макета в каталоге layout-large-land . Технически это реализуется путем проверки указанных квалификаторов и выполнения кода внутри конфигурации () только в том случае, если их значения совпадают.Следовательно, использование конфигурации () не ограничивается только DSL: например, вы можете безопасно вызывать функции Android SDK, которых нет в старых версиях системы, используя конфигурацию (fromSdk = ) {/ * code * /} .

Полный список поддерживаемых квалификаторов доступен здесь.

Создание пользовательского вида

Самый простой способ включения ваших собственных представлений в DSL - это создание ваших собственных функций, подобных построителю, но, поскольку это требует много времени, Anko теперь поддерживает более быстрый способ:

 frameLayout {
    customView  {
        backgroundResource = R.drawable.custom_view_bg
    } .linearLayout (ширина = matchParent)
} 

Реализовано через Java Reflection. Хотя это медленнее, чем обычные функции DSL, это намного проще при создании прототипа.

appcompat.v7 Просмотры и свойства

Мы сделали первый шаг к поддержке библиотеки appcompat.v7 Android. Функции расширения для классов View в пакете поддержки и свойства расширения для его атрибутов добавлены в Anko. Тонирование виджетов пока не поддерживается, мы надеемся реализовать его в более поздних версиях.

Удалены функции DSL верхнего уровня для простых представлений

Поскольку очень маловероятно, что в качестве представления содержимого ваших действий будет простое представление без контейнера (например, TextView), мы удалили функции DSL для таких представлений для приемников Activity и Fragment . В маловероятном случае необходимости такого представления на верхнем уровне используйте функцию-оболочку UI () :

 UI {
    textView (R.string.name)
} 

Ваш отзыв приветствуется

Anko находится под лицензией Apache License 2.0, и проект доступен на Github.
Ваши отзывы и запросы на включение приветствуются!

макетов Anko: основы - видеоурок по Kotlin среднего уровня для разработчиков Android

Обзор

Стенограммы

Файлы упражнений

Просмотр в автономном режиме

Детали курса

Kotlin теперь официально поддерживается Google как язык разработки для Android.Если вы - разработчик среднего уровня, заинтересованный в получении дополнительных сведений о Kotlin, этот курс может помочь вам познакомиться с этим кратким и забавным языком, узнав о его эффективности и возможностях в разработке для Android. Курс начинается с общего обзора того, что может предложить Kotlin, а затем углубляется в обсуждение функций и свойств расширения, в том числе того, как использовать плагин Kotlin Android Extensions. В нем также объясняется, как работать с Anko, и дается обзор некоторых основных артефактов библиотеки: общих объектов, макетов и сопрограмм.Подводя итоги, в курсе рассказывается, как работать с коллекциями.

Инструктор

  • Эннис Дэвис

    Технический директор Meetup | Мы нанимаем!

    Аннис Дэвис - руководитель инженерных разработок, спикер международных конференций и автор.

    В настоящее время Аннис - технический директор Meetup. На Meetup она помогает создать будущее настоящего сообщества, где люди появляются, делают что-то и действительно разговаривают друг с другом. Аннис также является экспертом по разработке Google. Это означает, что она занимается разработкой видео, публикаций в блогах и конференций для сообщества разработчиков. Она очень гордится своей работой и увлечена ею. Ее конечная цель в отношении технологий - поделиться своим опытом в области технологий и инженерии, чтобы вдохновить других сделать то же самое.

    Узнать больше

    Видеть меньше

Навыки, описанные в этом курсе

Зрители этого курса

6997 человек смотрели этот курс

Связанные курсы

.

Добавить комментарий

Ваш адрес email не будет опубликован.

2022 © Все права защищены. Карта сайта