От слов пора переходить к делу. А дело простое – обработчик события при нажатии кнопки. Вот только разработчики Android решили нагнать туман на привычные всем термины и предлагают свои.

Обработчик событий называют лиснером (англ. listener), и создавать его придется полностью в ручном режиме. В Delphi или My Visual Database для создания заголовка достаточно кликнуть по пустой строке в редакторе свойств, чтобы в редакторе исходного текста появилась заготовка, привязанная к месту. В Android Studio сначала нужно написать код, а после выбрать его в выпадающем списке свойства компонента. Или прописать вручную в текстовом редакторе разметки.

Но прежде нужно добавить кнопку на разметку экрана. Для этого выбираем в дереве файлов проекта activity_main.xml, переведя редактор в режим Design. В закрепленном окошке Palette находится двухуровневый список визуальных компонентов. Находим Buttons>Button и тянем его в область редактирования.

Теперь в файле MainActivity.kt пишем функцию onClickButton(). После чего название этой функции вставляем в свойство кнопки onClick.

package com.example.myapplication6

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    fun onClickButton(view:View) {
        val tvText = findViewById<TextView>(R.id.MyText)
        tvText.text =  getString( R.string.label_caption )
    }
}Code language: Kotlin (kotlin)

У автора курсов текст, который должен отобразиться, задается прямо в коде, но я подумал, что надо сразу приучаться к правилам хорошего тона и хранить текстовые сообщения в ресурсах, поэтому, погуглив, нашел нужное – функцию getString(), а в файл strings.xml добавил ещё один ресурс – надпись для отображения в метке при нажатии на кнопку:

<resources>
    <string name="app_name">My Application 6</string>
    <string name="label_caption">Бумс!</string>
</resources>Code language: HTML, XML (xml)

Обратите внимание на R – это класс для доступа к ресурсам. Доступ поименованный, при наборе в редакторе хорошо работает автозавершение.

Функция findViewById – это аналог метода FindComponent у формы в My Visual Database: она возвращает элемент экрана по его ID. Хотя ID – это число, при написании кода используется имя ресурса (R.id.MyText), а перед присвоением переменной приводится к нужному классу, в нашем случае – TextView.

Переменные? Объекты!

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

  • var – объявление переменной
  • val – объявление переменной с фиксированным значением

После того, как переменная задана (а задается она сразу с начальным значением, которое может быть вычислено с помощью выражения), выясняется, что это не совсем переменная, а… объект (экземпляр заданного класса), у которого имеется множество методов (преобразование, сравнение и т.д.). Но я буду по старинке называть их типами данных. Вот некоторые из них:

Целые числа

ТипОбъявлениеДиапазонПамять
Bytevar a:Byte = 0-128 .. 1271 байт
Shortvar a:Short = 0-32768 .. 327672 байт
Intvar = 0
var:Int = 0
-231 .. 231 – 14 байт
Longvar a:Long = 0
var a = 0L
-263 .. 263 – 18 байт

Целые числа без знака

ТипОбъявлениеДиапазонПамять
UBytevar a:UByte = 0u0 .. 2551 байт
UShortvar a:UShort = 0u0 .. 655352 байт
UIntvar:UInt = 0u
var a = 0u
0 .. 232 – 14 байт
ULongvar a:ULong = 0u0 .. 264 – 18 байт

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

  • 0x – шестнадцатеричное представление; 0xFA04B7
  • 0b – двоичное представление; 0b100101011

Числа с плавающей точкой

ТипОбъявлениеМантиссаСтепеньДиапазонПамять
Floatvar a:Float = 0f
var a = 0f
var a = 0F
24 бита8 бит-3.4*1038 .. 3.4*10384 байт
Doublevar a:Double = 0.0
var a = 0.0
53 бита11 бит±5.0*10-324 .. ±1.7*103088 байт

Логический

ТипОбъявлениеЗначенияПамять
Booleanvar a:Boolean = false
var a = false
true или false1 байт

Символьный

ТипОбъявлениеЗначенияПамять
Charvar a:Char = ‘0’
var a = ‘0’
Одинарный символ2 байт

Строковый

ТипОбъявлениеЗначенияПамять
Charvar a:String = “0”
var a = “0”
Последовательность символов2 байт на каждый символ

Символы могут быть заданы управляющими последовательностями:

  • \t – табуляция
  • \n – перевод строки
  • \r – возврат каретки
  • \’ – одинарная кавычка
  • \” – двойная кавычка
  • \\ – обратный слеш
  • \$ – доллар

Особое отношение к доллару вызвано тем, что если написать его без обратного слеша, то за ним должно следовать имя переменной, которое вставляется в текст. Где-то я это уже видел…. точно, в PHP!

tvText.text = "\$Привет, $MyName " // показать переменную в тексте; если нужен доллар в тексте, то экранируем егоCode language: Kotlin (kotlin)

Обычно Kotlin игнорирует перевод строки в исходном тексте, но тройные кавычки позволяют форматировать строковые данные непосредственно в редакторе:

val text: String = """
                   Этот текст будет напечатан в три строки,
                   со всеми символами внутри:
                   "Двойными" и 'одинарными' кавычками.
                   """Code language: Kotlin (kotlin)

Область видимости

Переменные можно объявлять либо внутри класса, либо внутри метода класса. Это определяет область видимости переменной – класс или метод. Приятно, что такое зло, как глобальные переменные, в Kotlin вырублено под корень.

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

Если после названия класса в объявлении переменной указать вопросительный знак, то это будет означать, что данная переменная может быть пустой, то есть содержать значение null. Тогда инициализация и дальнейшее использование этой переменной класса будет выглядеть так:

class MainActivity : AppCompatActivity() {
    var tvText:TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tvText = findViewById(R.id.MyText)
    }
    fun onClickButton(view:View) {
        tvText?.text =  getString( R.string.label_caption )   // "Ку-ку!"
    }
}Code language: Kotlin (kotlin)

Но есть и другая возможность: использовать ключевое слово lateinit (отложенная инициализация).

class MainActivity : AppCompatActivity() {
    lateinit var tvText:TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tvText = findViewById(R.id.MyText)
    }
    fun onClickButton(view:View) {
        tvText.text =  getString( R.string.label_caption ) 
    }
}Code language: Kotlin (kotlin)

Так как в Kotlin можно (а я считаю, что – нужно!) указывать тип (класс) переменной явно при объявлении переменной, то желательно этим пользоваться регулярно. Отмечу, что это позволяет опустить приведение типа при использовании функции findViewById()

Смотрим внимательно

Особенность рассматриваемого видеокурса состоит в том, что автор будет несколько раз “менять показания” относительно того, как делать те или иные действия. С одной стороны это расширяет кругозор, с другой стороны придется переучиваться прямо по ходу обучения. Я рекомендую отнестись к предлагаемым видеоматериалом критически, и воспринимать их только как отправную точку.

В частности, я чуть выше отметил, что слушатель (обработчик события) приходится создавать вручную. Но это не совсем так: если изменить последовательность действий, то можно заставить среду разработки создать заготовку данной функции. Для этого сначала прописываем в свойство onClick название метода, а затем отправляемся в редактор формы. Там мы используем меню “лампочки”, которая предлагает создать данную функцию в исходном коде:

А вот если вы захотите добавить слушателя непосредственно в программном коде, то возможно вызвать специальную языковую конструкцию – setOnclickListener{}, внутри фигурных скобок которой можно написать реализацию функциональности. Если честно – весьма сомнительное удобство. На мой взгляд читать и понимать подобный код будет затруднительно. Однако, я видел раньше подобные примеры в других видеогайдах по созданию мобильных приложений.

Забегая вперед скажу, что существует механизм, автоматически создающий для всех элементов интерфейса переменные. В Delphi это происходит автоматически при добавлении компонента на форму, в My Visual Database эти переменные также доступны из скрипта через свойства формы, в Andriod Studio – это отдельная опция.

Ссылки

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *