На этом шаге мы рассмотрим размещение данных в визуальных компонентах.
Чтобы отобразить характеристики персонажа в UI, надо сначала получить все визуальные элементы для вывода текста, использовав функцию с именем findViewByld(), доступную в MainActivity.kt (через наследование). Функция findViewByld() принимает id визуального элемента (идентификаторы android:id, объявленные в XML) и возвращает ссылку на визуальный элемент, если элемент с таким идентификатором существует.
В MainActivity.kt добавьте в onCreate() поиск каждого визуального элемента, необходимого для отображения данных, по его id и сохраните ссылки в локальных переменных.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val nameTextView = findViewById<TextView>(R.id.nameTextView) val raceTextView = findViewById<TextView>(R.id.raceTextView) val dexterityTextView = findViewById<TextView>(R.id.dexterityTextView) val wisdomTextView = findViewById<TextView>(R.id.wisdomTextView) val strengthTextView = findViewById<TextView>(R.id.strengthTextView) val generateButton = findViewById<Button>(R.id.generateButton) } }
Рис.1. Первый шаг импортирования классов
В начале контекстного меню появится строка Import (рисунок 2).
Рис.2. Второй шаг импортирования классов
Выберите ее, и красное подчеркивание исчезнет. Сделайте то же самое для Button.
Далее, присвойте характеристики персонажа свойству класса MainActivity (фрагмент 1 на рисунке 3).
class MainActivity : AppCompatActivity() { private var characterData = CharacterGenerator.generate() override fun onCreate(savedInstanceState: Bundle?) { . . . . } }
class MainActivity : AppCompatActivity() { private var characterData = CharacterGenerator.generate() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) . . . . characterData.run { nameTextView.text = name raceTextView.text = race dexterityTextView.text = dex wisdomTextView.text = wis strengthTextView.text = str } } }
Рис.3. Объявление свойства characterData (1) и вывод характеристик персонажа на экран (2) (MainActivity.kt)
В этом коде, который записывает характеристики персонажа в текстовые поля, есть несколько интересных деталей. Во-первых, используется функция run(), чтобы сократить код настройки элементов просмотра характеристик персонажа за счет сужения области видимости свойств с характеристиками персонажа экземпляром characterData.
Кроме того, запись текста производится с использованием обычного синтаксиса присваивания, как тут:
nameTextView.text = name
Для того же эффекта в Java, а не в Kotlin вы бы написали:
nameTextView.setText(name);
В чем разница между ними? Android - это фреймворк Java, и в соответствии со стандартными соглашениями доступ к полям в Java выполняется с использованием методов чтения/записи. Напоминаем, что AppCompatActivity, элементы TextView и все компоненты платформы Android написаны на Java, и вы обращаетесь к ним, когда используете Kotlin для написания приложения на Android.
Если бы вы взаимодействовали с nameTextView из класса Java, то использовали бы стандартный синтаксис Java (setText, getText).
Но так как вы взаимодействуете с Java-классом TextView из Kotlin, то Kotlin транслирует соглашение об использовании методов чтения/записи в свой эквивалент этого соглашения - использование синтаксиса обращения к свойствам. Это не требует добавления дополнительного кода или изменений. Kotlin автоматически "строит мост" между стилем Java и стилем Kotlin, потому что он изначально создавался с прицелом на бесшовную совместимость с Java.
Снова запустите Samodelkin в эмуляторе. В этот раз вы увидите, что характеристики героя были извлечены из CharacterGenerator и записаны в UI (рисунок 4).
Рис.4. Samodelkin выводит информацию
На следующем шаге мы рассмотрим реализацию записи данных в отдельной функции.