Как помните, в прошлом уроке мы стали создавать наше первое приложение “Быки и коровы”. В готовом виде это приложение есть в моём аккаунте по этой ссылке (чтобы понимать что мы хотим делать):
Быки и коровы в каталоге RuStore
В этом уроке вы будете создавать среду взаимодействия с пользователем, которую часто называют “интерфейс пользователя”, а креативные специалисты предпочитают название Frontend. Если простыми словами – это то, что видит на экране пользователь. Как понимаете, есть и то, что тоже является работой программы, но что пользователь не видит, но об этом позже.
Смысл этой детской игры достаточно прост. Играют двое (в данном случае одним из игроков будет вычислительная среда мобильного телефона, а вторым – человек / пользователь). Один загадывает число из 4-х знаков, все цифры которого различные, второй игрок, пользуясь подсказками должен угадать узнать это число. Загадывать будет компьютер, отгадывать человек, компьютер/мобильник/планшет будет давать подсказки. Подсказки даются следующим образом. Если в называемом числе есть цифра в загаданном и находится в своём разряде (на таком же месте), то это “бык”, а если есть такая цифра, но не находится на своём месте, то это “корова”. Если угаданных цифр несколько, то соответствующее число будет быков и коров. Как понимаете название игры весьма условно, т.к. реальных быков и коров вы в этой игре не увидите. Игра эта тренирует логическое мышление у детей, а также память, способность целостно представлять решение задачи, искать рациональные логические решения. Связано это с тем, что любое число можно отгадать за определенное минимальное число вопросов. Поясню подробно. Например:
Компьютер загадал число
4678
Мы пытаемся отгадать и называем первое придуманное число
2684
Компьютер должен нам сообщить, что в нашем числе 1 бык и 2 коровы:
бык – это цифра 6, она есть в загаданном числе и находится в 3-м разряде (разряды считаются справа-налево).
коровы две – это цифры 4 и 8, т.к. они тоже есть в числе, но стоят не в строгом соответствии разрядов.
Сложность тут в том, что компьютер нам не скажет, что именно является быком, а что коровами. Просто сообщает что они есть и сколько их. Теперь мы уже точно знаем, что какая-то из цифр нашего придуманного числа точно стоит на своём месте, а ещё есть две, но не на своём. По этому мы используя эту информацию должны снова придумать число и сказать его компьютеру, например мы говорим
2184
Компьютер нам сообщит после этого, что в этом числе только 2 коровы. По этому мы теперь точно знаем, что 6 была быком. Т.е. одну цифру мы знаем точно и где она находится в угадываемом числе. Однако, мы могли и не угадать с первого раза, а назвать число, например 1874 – это было бы тоже 1 бык и 2 коровы, мы бы от этого только запутались. В этом и заключается интерес – как правильно мы используем каждую очередную подсказку, как правильно называем вариант и как быстро сможем узнать загаданное компьютером число. Помню нас школьников эта игра очень увлекала в 3-м классе.
Итак, задача поставлена, теперь нужно создать пользовательский интерфейс, который будет отображать на экране телефона текущее состояние, уже введенные нами варианты, сколько в каждом было быков и коров и ещё должно быть поле ввода цифр, которое и будет принимать от нас каждый новый вариант числа. В последствии алгоритм будет его сравнивать с загаданным числом и выдавать результат сравнения.
Рассмотрим подробнее как выглядит файл MainActivity.xml, в котором на прошлом уроке вы меняли “Hello, world!” на “Привет, мир!”.
Файл выполнен в формате XML, об этом свидетельствует надпись вначале
“<?xml”
Тут придётся немного рассказать вкратце о его структуре, тем более что формат очень популярен и используется не только в Андроид Студии. Файл состоит из контейнеров, которые образно выглядят вот так (его границы, а также внутренности – тело):
<ИмяКонтейнера Атрибут1=”значение1″ Атрибут2=”значение2″ ещё атрибуты…>
…тут что-то находится внутри и называется телом…
</ИмяКонтейнера>
Т.е. контейнер состоит из открывающего элемента и закрывающего элемента, а внутри – тело. Эти элементы начала и конца называются открывающий тэг и закрывающий тэг. Конец контейнера определяется почти также как и его начало, у него имя точно такое же, но нет атрибутов и перед именем стоит косая черта (правый слеш /). Контейнеры нужны чтобы внутрь переменной ИмяКонтейнера запихнуть большую кучу всякой информации.
Название контейнеров, атрибутов в данном файле строго регламентировано и должно называться строго определенными названиями. Значение атрибутов должны быть только определенного для них типа и в строго определенном диапазоне значений, если такой диапазон предусмотрен.
Вторая конструкция xml файла – это просто тэги. Это тот же контейнер, только без тела внутри (у него нет закрывающего тэга). Но открывающий выглядит чуть по другому:
<ИмяТэга Атрибут1=”значение1″ />
т.е. правый слэш стоит в конце в тэге, атрибутов тоже любое количество, закрывающего нет и тела тоже нет.
Сами тэги, как наверно уже поняли – это то, что находится между угловыми скобками (они же знаки меньше-больше) :
<тут всё, что относится к тэгу вместе с атрибутами>
Атрибуты – это некая характеристика тэга, его параметр, иная информация относящаяся непосредственно только к этому тэгу.
В таких файлах xml и находится как раз полное описание того, что находится на экране…но это не точно)))…но об этом гораздо позже. Сейчас должны знать, что какой файл MainActivity вы сделаете, то это на экране и будет. Вопрос, а что конкретно можно описать там?
Если вы держите в руках мобильный телефон на Android не впервые в жизни (если это не так, то уже настало время это поделать), то наверно видели, что на экране могут быть:
- обычный текст
- поля для ввода какого-то текста
- картинки
- кнопки
- различные переключатели тип вкл/выкл
- различные выборы из списков
- перечни
- так называемые радиокнопки (несколько кружочков с текстом, где можно выбрать только один из нескольких вариантов)
- чекбоксы (где можно поставить галочку)
- географические карты
- и т.п.
Это всё можно и нужно описать в этом MainActivity.xml
По этому, чтобы далеко не ходить, разработчики Android так и решили называть тэги и контейнеры по типу того объекта, которые пользователю нужно показать. Например, взгляните на наш этот файл и посмотрите внимательно в каком тэге какой атрибут мы поменяли, когда изменили текст “Hello, world!” на “Привет, мир!”. Это атрибут “android:text” тэга TextView. Т.е. тэга, который выводит на экран просто обычный текст. Посмотрите, какие ещё у этого тэга атрибуты:
android:layout_width – это ширина этой текстовой области
android:layout_height – это высота этой текстовой области
есть и ещё другие атрибуты, которые мы будем рассматривать в следующих уроках, пока рано.
Ещё заметьте, что ширина и высота заданы не цифрами, а служебным словом “wrap_content”. Всё дело в том, что разработка под Android идёт с учетом различных устройств, а если быть более точным – более 10 тыс. различных устройств. Все эти устройства имеют разные характеристики, и что важно – разные размеры экранов. Работа программиста заключается в том, чтобы ни на каком из этих экранов интерфейс пользователя не отобразился криво, чтобы всё влезло по ширине и высоте, чтобы слова правильно переносились, чтобы текст не выходил за пределы экрана и т.п. Это называет адаптивный интерфейс (или адаптивный дизайн), т.е. интерфейс, который будет пытаться подстроиться под каждый размер экрана каждого устройства. Если, например, вы укажете точную ширину в пикселях, то на крохотных экранах часть текста может оказаться либо не видна, либо переноситься по середине слова, а на больших экранах окажется много свободного неиспользуемого места справа. По этому стараются делать так, чтобы приложение автоматически попробовало по ширине нужной области, а если уж это не получится, то и стало бы переносить. Но все бы так и делали, если бы в дизайне иногда не требовалось разместить несколько объектов слева направо, например фраза “Введите логин:” и справа от него поле ввода логина. Если бы они оба были по ширине экрана или оба имели бы фиксированную ширину, то см. выше, что я только что написал – дизайн бы съехал. По этому придумано много различных вариантов задания ширины и высоты, а именно:
- в условных единицах, например, 50dp, 125dp
- по ширине содержимого текста, wrap_content. Т.е. какой ширины отображаемый текст, таким и будет ширина этого объекта. Удобно как раз для текста “Введите логин:”
- по ширине вышестоящего контейнера, а если его нет – экрана, match_parent
Всё тоже касается и высоты. Каждый из этих вариантов выбирается под конкретную задачу по мере необходимости.
Теперь, после того как вы немного сориентировались с тэгом TextView, обратите внимание в каком контейнере он сам располагается. Это контейнер с именем androidx.constraintlayout.widget.ConstraintLayout. Не нужно запоминать такое длинное название, это просто контейнер ConstraintLayout. Длинный путь нужен среде разработки чтобы она сама не запуталась где его внутри своих библиотек кода искать. Если вам потом придётся вводить его вручную, то среда разработки сама подскажет откуда она его будет брать, как только начнете набирать слова ConstraintLayout (без пробелов), тут обычно никаких ошибок не возникает. Теперь заметьте какую ширину и высоту этот контейнер имеет – match_parent, т.е. учитывая что над ним нет уже никакого контейнера, этот значит, что он будет во весь экран по ширине и высоте. ConstraintLayout – это специальный контейнер, который на экран ничего не выводит, он просто позволяет выстраивать на экране те элементы, которые у него внутри в определенном порядке и по определенным правилам. О нём позже.
С размером элемента TextView всё понятно, а как же поменять цвет текста, цвет фона, сделать текст более жирным или наклонным?- возможно спросите вы. Давайте теперь сменим подвкладку на эту (“Design”):
Теперь нужно кликнуть на компонент TextView:
После этого справа отобразятся все его свойства, также обратите внимание на ползунок Scroll, который означает, что это лишь часть атрибутов, а есть ещё, если протащить ползунок вниз:
Видно поле text со значением “Привет, мир!”, видны layout_width и layout_height и ещё много чего. Далее вниз будут и жирность и наклон и т.п., находятся в группе textStyle:
Цвет текста – это textColor, а цвет фона – background
ОЧЕНЬ ВАЖНО! Заметьте как написан атрибут textColor – буква С – заглавная. В языке Java, а также и ещё во многих языках, textcolor и textColor воспринимаются как совершенно разные переменные и атрибуты, т.е. мы имеем дело с регистр чувствительным синтаксисом.
Задание по уроку:
1. Установите текст поля вместо “Привет, мир!” на текст “МОИ ХОДЫ”
2. Разберитесь самостоятельно, используя поисковик Гугл или Яндекс (это в будущем придётся делать вам часто, лучше сразу привыкать) как задаётся цвет текста в HTML, как правильно записывается цвет в цифровом виде RGB (красный, зеленый, синий). Как примерно происходит смешение трех цветов формата RGB. Установите на текст “МОИ ХОДЫ” цвет текста темно-сиреневый (насколько тёмно и сиреневый – на ваш вкус). Пришлите в коммент скриншот что получилось.
3. Попробуйте установить цвет фона для всего отображаемого экрана на бирюзовый
Если всё получилось как нужно – молодцы! Если нет, давайте разберёмся что не так.