- Android – создание простого пользовательского интерфейса
- Создаем приложение для ANDROID быстро и просто
- Рисование собственных представлений (View) в Android
- Получите полный контроль над представлением и оптимизируйте его производительность
- Введение
- Общий подход
- Обновление представления
- invalidate()
- requestLayout()
Android – создание простого пользовательского интерфейса
Создание простого пользовательского интерфейса в android приложении
Графический интерфейс андроид приложений строится на иерархии из элементов двух типов: View и ViewGroup. Элементами типа View являются любые дочерние элементы пользовательского интерфейса (UI widgets), такие как кнопка (button), поле для ввода и пр. ViewGroup – это невидимый контейнер графических элементов (вышеупомянутых view), определяющий их размещение на интерфейсе. Это может быть вертикальный, горизонтальный список или таблицы элементов.. Один ViewGroup может содержать множество view и другие ViewGroup. Оперируя различными графическими элементами и контейнерами эл-в можно создавать интерфейсы.
Иерархия view и viewGroup при построении пользовательского интерфейса в android
Перейдем от теории к практике, изменим стандартный экран приложения (HelloWorld), который отображается при запуске (ну или можете создать новое приложение 😉 ). Откроем текущее отображение экрана (файл activity_main.xml из директории res/layout).
Создание LinearLaout
Обратите внимание, что перед Вами открылся визуальный редактор интерфейса (Graphical layout). Все действия можно выполнять тут, а можно перейти в режим отображения кода ( activity_main.xml – слева внизу под набором доступных элементов). Я использую оба варианта. Как по мне удобно накидать необходимых элементов с помощью графического редактора а потом уже точечно по необходимости подправить каждый элемент в коде. Выбирайте удобный для Вас способ, но настоятельно рекомендую разобраться с тем, что пишется в коде.
По умолчанию на форме находится RelativeLayout (ViewGrop) и текстовое поле (view). Подробно о каждом контейнере поговорим позже, сейчас удалим текст с экрана и поменяем стандартный Layout на LinearLaout, в который добавим поле android:orientation и установим значение «horizontal» .
LinearLaout – это ViewGrop, который отображает дочерние элементы один за другим в вертикальном или горизонтальном формате, в зависимости от значения поля android:orientation . Используя линейный контейнер графические элементы на экране будут отображены в том же порядке, в котором они находятся в xml файле.
Поля android:layout_width и android:layout_height должны быть указаны для всех графических элементах для указания их размера. Учитывая, что наш LinearLaout это корневой элемент интерфейса, мы указываем ему заполнить все пространство экрана, устанавливая width и height равными «match_parent» .
Создание простого интерфейса в android с LinearLayout
Добавление текстового поля
Далее добавим в интерфейс текстовое поле для ввода (элемент EditText ). Как и при использовании любого другого графического элемента, необходимо указать некоторые основные свойства данного объекта. В нашем случае элемент задается следующим кодом:
Добавление поля для ввода текста в android интерфейс
В этом случае свойства android:layout_width и android:layout_height заданы как «wrap_content» , указывая что элементы должны быть такого размера, чтобы заполнить содержимое отображения. Если Вы укажите значение «match_parent» , то поле для ввода заполнит весь экран т.к. указано что оно должно растянуться до размера своего предка – LinearLayout .
Свойство android:id – это уникальный идентификатор для графического элемента. Он будет использоваться чтобы обратиться к элементу из кода программы, например, для чтения значения.
Знак собачки ( @ ) необходим, когда идет обращение к любому ресурсу из XML. Он следует после указания типа ресурса ( id в текущем случае), слэш, потом имя ресурса ( edit_message ).
Знак плюса ( + ) необходим только в случае первого объявления ID ресурса. Когда происходит компиляция, SDK tools использует ID чтобы создать новый ресурс в файле gen/R.java . В дальнейшем при использовании идентификатора не нужно указывать знак плюса.
Свойство android:hint – это значение той строки, что будет отображаться в поле для ввода по умолчанию (когда оно пустое). Вместо того, чтобы задавать строку в файле разметки, используется запись «@string/edit_message», кот. говорит о том, что значение строки берется с файла ресурсов строк. “edit_message” – это ключ, по которому будет получено значение строки. Т.к. мы обращаемся к конкретному ресурсу (а не просто идентификатору) нет необходимости использовать знак плюса. В данный момент, из-за того, что строка в файле ресурсов еще не объявлена, компилятор выдает ошибку. Исправим ее, добавив соответствующий ресурс!
Добавление строки в файл ресурсов (strings.xml)
Все строки, что используются в интерфейсе должны быть объявлены в отдельном файле ресурсов. В дальнейшем такой подход значительно упростит изменение текстов приложения и добавления локализаций (других языков, кот будет поддерживать приложение).
По умолчанию, в проекте уже есть ресурсный файл со строками: res/values/strings.xml . Добавьте новую строку с именем «edit_message» и значением “Enter a message.” Так же Вы можете удалить строку “hello_world”. И можно сразу добавить строку, которую мы вскоре будем использовать для кнопки: “Send” с ключом «button_send» .
В результате файл strings.xml выглядит следующим образом (в режиме кода! переключатель слева внизу ;)):
android resources – strings.xml
Добавление кнопки на экран приложения
Далее добавим на форму кнопку, следующую за полем для ввода. Свойства height и width установлены в «wrap_content» , что говорит о том, что кнопка будет размером, необходимым для текста на кнопке. Атрибут android:id не установлен т.к. он не будет использоваться в коде приложения.
В результате получается следующий интерфейс:
Создаем простой android интерфейс
Размещение поля для ввода по всем ширине экрана
Оптимизируем его немного: растянем поле для ввода по ширине экрана. В данный момент ширина обоих графических элементов установлена в «wrap_content» . Для кнопки данное значение нормально, но для поля для ввода – не очень т.к. пользователь может ввести строку длиннее, чем поместиться в элемент (можете запустить сейчас приложение и попробовать ввести длинное значение 😉 ).
Итак, чтобы растянуть поле на неиспользуемую часть экрана в LinearLayout (в других контейнерах невозможно указать вес для графического элемента! Там используются другие свойства), необходимо указать атрибут weight ( android:layout_weight ).
Свойство weight это число, указывающее на то, сколько оставшегося пространства будет занимать один элемент на экране среди множества других. Т.е. фактически задаются пропорции занимаего пространства каждым графическим элементом. К примеру, есть 2 элемента, у одного вес равен 2, у второго – 1. на экране первый элемент будет занимать 2/3 всего пространства а второй – оставшиеся место.
По умолчанию вес каждого элемента равен нулю. Если для любого элемента указать значение веса больше нуля, этот элемент растянется по “свободному” пространству экрана. Мы так и сделаем, указав полю ввода вес равный одному. В результате форма должны быть представлена следующим кодом:
Код простого интерфейса android приложения
А сам интерфейс будет выглядит вот так:
Простой пользовательский интерфейс andoird приложения
Т.к. редактировался главная и единственная форма приложения, ее Вы и увидите при запуске приложения ;).
Источник
Создаем приложение для ANDROID быстро и просто
Сегодня я хотел бы поделиться с Вами, как быстро и просто можно создать приложение для Android с базовыми знаниями HTML CSS и JS. По данному примеру код на Java для Android будет минимальным. Благодаря платформе XAMARIN приложения для мобильных телефонов можно делать в Visual Studio.
▍Шаг 1 — Переходим на сайт и Скачиваем бесплатную версию Community.
▍Шаг 2 — Запускаем установку и выбираем параметры. Нас интересует XAMARIN. Но Вы также можете выбрать другие параметры.
После успешной установки мы можем создать свой первый проект.
▍Шаг 3 — Запускаем Visual Studio. Создать проект. В фильтре пишем xamarin, платформа Android, язык c# (Если желаете другой язык можете его выбрать)
▍Шаг 4 — Далее. Указываете имя для своего приложения, выбираете каталог где его сохранить. Создать.
▍Шаг 5 — Указываем пустое приложение и выбираем минимальную версию андроида для запуска этого приложения.
▍Шаг 6 — Жмем ок. Visual Studio автоматически создает код для приложения
Мы можем его запустить в эмуляторе, который идет комплекте с Visual Studio нажав клавишу F5.
▍Шаг 7 — Теперь немного модифицируем код. В данном случае мы вообще не будем использовать Java. Так как мы будем кодить на C#.
Приводим код к такому виду. Здесь мы создаем WebView контейнер который будет грузить локальный HTML файл, который находится в проекте в папке Assets.
▍Шаг 8 — Создадим там папку Content.
▍Шаг 9 — Добавим в папку Content файл login.html
▍Шаг 10 — Далее уже пишем на привычном нам HTML CSS JS. Можем нажать на F5 и увидеть результат нашей работы.
По такому принципу можно создать приложение быстро и просто. Файлы html будут выглядеть одинаково на всех устройствах. То есть, Вы можете сделать приложения для Android и iOS с одинаковым интерфейсом. Не надо изучать сложные языки разметки, не надо изучать сложные макеты (сториборды) на iOS. Все можно сделать на HTML.
В идеале, вместо локальных файлов можно сделать загрузку со стороннего сайта. В этом случае Вы можете менять контент приложения без его обновления в AppStore и Google Play.
Q: Но как быть с функциями самой платформы? Пуш сообщения? Как взаимодействовать с самой платформой?
Все очень просто! JavaScript можно использовать для вызова функций Android:
▍Шаг 1 — Немного модифицируем наш файл MainActivity
▍Шаг 2 — Далее создаем класс JavaScriptInterface на который будет ругаться Visual Studio
Мы видим, что теперь программа ругается на Export так как не знает что это такое.
▍Шаг 3 — Добавим нужную библиотеку
▍Шаг 4 — В фильтре напишем mono
▍Шаг 5 — Найдем Export и поставим галочку
▍Шаг 6 — Жмем ок и видим что ошибка пропала.
Так вы можете подключать библиотеки если вдруг Visual Studio ругается на что то.
Данная функция это показ всплывающей информации на экране. Она выполняется именно на платформе Андроида. То есть мы можем написать в HTML файле вызов функции Андроида. Получается полное дружелюбие двух платформ по JavaScript интерфейсу. Данные можно передавать туда сюда. Вызывать переход от одной активити в другую. Все через HTML + JavaScript.
Немного модифицируем файл login.htm:
Теперь при нажатии на кнопку HTML вызывается функция Toast андроида и выводиться сообщение пользователю.
Источник
Рисование собственных представлений (View) в Android
Получите полный контроль над представлением и оптимизируйте его производительность
В преддверии старта курса «Android Developer. Professional» приглашаем всех желающих принять участие в открытом вебинаре на тему «Пишем gradle plugin».
А пока делимся переводом полезного материала.
Введение
Разработчики постоянно проектируют различные виды пользовательских интерфейсов с помощью XML, но в дополнение к этому можно довольно легко освоить создание собственных представлений, которые открывают новые преимущества и позволяют избежать повторного использования шаблонного кода.
В Android доступен широкий набор готовых виджетов и макетов для создания пользовательского интерфейса, однако они не могут удовлетворить все требования наших приложений. И здесь на помощь приходит возможность создания собственных представлений. Создав собственный подкласс представления, можно получить максимально полный контроль за внешним видом и функционалом экранного элемента.
Прежде чем приниматься за работу с собственными представлениями, полезно изучить жизненный цикл представления.
Зачем создавать собственные представления?
Чтобы реализовать собственное представление, в большинстве случаев понадобится больше времени, чем если использовать обычные представления. Создавать собственные представления стоит лишь в том случае, если нет другого, более простого способа реализовать нужную вам возможность или если у вас есть какие-либо из указанных ниже проблем, которые можно устранить за счет создания собственного представления.
Производительность: в вашем макете много представлений и вы хотите оптимизировать их, нарисовав одно, более легкое собственное представление.
Имеется сложная иерархия представлений, которую трудно использовать и поддерживать.
Необходимо создать специализированное представление, требующее рисования вручную.
Общий подход
Чтобы приступить к созданию компонентов для реализации собственных представлений, необходимо выполнить следующие основные шаги.
Создать класс, расширяющий базовый класс или подкласс представления.
Реализовать конструкторы, использующие атрибуты из XML-файла.
Переопределить некоторые методы родительского класса (onDraw(), onMeasure() и т. д.) в соответствии с нашими требованиями.
После выполнения этих шагов созданный расширяющий класс можно использовать вместо представления, на основе которого он был создан.
Пример
В одном из моих проектов мне нужно было создать круглый виджет TextView для отображения количества уведомлений. Чтобы достичь этой цели, нужно создать подкласс TextView.
Шаг 1. Создадим класс с именем CircularTextView .
Шаг 2. Расширим класс виджета TextView. Здесь под TextView в IDE выдается ошибка, в которой сообщается, что у этого типа есть конструктор и он должен быть инициализирован.
Шаг 3. Добавим конструкторы в класс.
Это можно сделать двумя способами.
Первый способ добавления конструкторов в класс показан ниже.
Другой способ заключается в добавлении аннотации @JvmOverloads к вызову конструктора, как показано ниже.
Часто нас сбивает с толку то, что у представления есть несколько разных типов конструкторов.
View(Context context)
Простой конструктор для динамического создания представления из программного кода. Здесь параметр context — это контекст, в котором работает представление и через который можно получить доступ к текущей теме, ресурсам и т. д.
View(Context context, @Nullable AttributeSet attrs)
Конструктор, который вызывается при формировании представления из XML-файла. Он вызывается, когда представление создается из XML-файла, содержащего атрибуты представления. В этом варианте конструктора используется стиль по умолчанию (0), поэтому применяются только те значения атрибутов, которые есть в теме контекста и заданном наборе AttributeSet .
Шаг 4. Самый важный шаг в отрисовке собственного представления — это переопределение метода onDraw() и реализация необходимой логики отрисовки внутри этого метода.
Метод OnDraw (canvas: Canvas?) имеет параметр Canvas (холст), с помощью которого компонент представления может отрисовывать себя. Для рисования на холсте необходимо создать объект Paint.
Как правило, процесс рисования определяется двумя аспектами:
что рисовать (определяется объектом Canvas);
как рисовать (определяется объектом Paint).
Например, Canvas предоставляет метод для рисования линии, а Paint предоставляет методы для определения цвета этой линии. В нашем случае объект Canvas в классе CircularTextView предоставляет метод для рисования окружности, а объект Paint заполняет ее цветом. Проще говоря, Canvas определяет, какие фигуры можно нарисовать на экране, а Paint определяет свойства нарисованных фигур — цвет, стиль, шрифт и т. д.
Давайте займемся кодом. Мы создаем объект Paint и присваиваем ему некоторые свойства, а затем рисуем фигуру на холсте (объект Canvas), используя наш объект Paint. Метод onDraw() будет выглядеть так:
IDE показывает предупреждение о том, что следует избегать выделения объектов во время операций отрисовки или операций с макетом. Это предупреждение возникает потому, что метод onDraw() много раз вызывается при отрисовке представления, в котором каждый раз создаются ненужные объекты. Поэтому, чтобы избежать ненужного создания объектов, мы вынесем соответствующую часть кода за пределы метода onDraw() , как показано ниже.
При выполнении отрисовки всегда помните о том, что следует повторно использовать объекты вместо создания новых. Ваша IDE может указать на потенциальные проблемы, но полагаться на нее не стоит. Например, она не сможет отследить случай, когда объекты создаются внутри методов, вызываемых из метода onDraw() . Поэтому лучше проверять все самостоятельно.
Шаг 5. Мы закончили с рисованием. Теперь давайте внесем этот класс представления в XML.
Добавьте этот XML-макет в вашу активность (Activity) и запустите приложение. Вот что будет на экране.
Выглядит неплохо, правда? Теперь сделаем так, чтобы значение динамическому свойству цвета в circlePaint назначалось из активности, а также добавим контур к кружку. Для этого в классе CircularTextView необходимо создать несколько методов-сеттеров, чтобы можно было вызывать эти методы и устанавливать свойства динамически.
Для начала давайте реализуем настройку цвета отрисовки. Для этого создадим сеттер, как показано ниже.
Теперь мы можем устанавливать цвет из нашей активности динамически, вызывая этот метод.
Неплохо, правда? Теперь давайте добавим контур к кружку. Контур будет задаваться двумя входными параметрами: шириной линии контура и ее цветом. Чтобы задать цвет линии контура, нам нужно создать объект Paint точно так же, как мы это делали для кружка. Чтобы задать ширину линии контура, мы создадим переменную, установим для нее нужное значение и используем его в методе onDraw() . Полный код будет выглядеть так:
Теперь в активности можно динамически настраивать эти атрибуты нужным образом.
Далее давайте запустим приложение, устанавливая различные цвета для нашего виджета.
Итак, теперь стало ясно, как динамически устанавливать свойства из активности, но возникает вопрос о том, как устанавливать атрибуты из XML. Продолжим наше исследование.
Для начала создадим файл с именем attrs.xml в папке values. Этот файл будет содержать все атрибуты для различных представлений, которые мы создаем сами. В приведенном ниже примере у нашего представления под названием CircularTextView имеется атрибут ct_circle_fill_color , который принимает значение цвета. Аналогичным образом мы можем добавить и другие атрибуты.
Затем нам нужно будет прочитать эти свойства в классе, который мы создали для реализации собственного представления. В блоке инициализации мы считываем набор атрибутов, как показано ниже.
Теперь просто переходим к XML-макету и устанавливаем значение свойства, соответствующее нужному цвету, после чего запускаем приложение. На выходе мы увидим нужный результат.
В моем случае результат был таким:
Примечание. При рисовании не задавайте жестко размер вашего представления, так как им могут воспользоваться другие разработчики с применением других размеров. Рисуйте представление в соответствии с его текущим размером.
Обновление представления
Итак, мы задали собственное представление. Если мы хотим обновлять представление при изменении какого-нибудь свойства или по какой-то другой причине, этого можно добиться двумя основными способами.
invalidate()
invalidate() — это метод, который инициирует принудительную перерисовку определенного представления. Проще говоря, метод invalidate() следует вызывать в случае, когда требуется изменение внешнего вида представления.
requestLayout()
Если в какой-то момент происходит изменение состояния представления, то метод requestLayout() сообщает системе представлений, что необходимо сделать перерасчет фаз «измерение» (Measure) и «макет» (Layout) для данного представления (измерение → макет → рисование). Проще говоря, метод requestLayout() следует вызывать в случае, когда требуется изменение границ представления.
Теперь, я надеюсь, вы знаете в общих чертах, как создавать собственные представления. Чтобы они демонстрировали отличную производительность, необходимо освоить все описанные здесь методы.
Источник