Android java view html

WebView

WebView — это компонент, который позволяет встраивать веб-страницы в приложения, своеобразный мини-браузер. Находится в разделе Containers.

В старых версиях Android WebView использовал движок WebKit. В Android 4.4 он стал использовать движок Chromium или Blink. В Android 5 появилось отдельное приложение System WebView, которое можно скачать из Play Market. Такое разделение позволило обновлять движок без обновления системы. На этом приключения не закончились. В Android 7.0 уже используется движок Chrome, а если этого браузера на устройстве нет, то используется System WebView. Подобные выкрутасы не прошли даром, программисты часто жалуются, что какой-то кусок кода не работает. Приходится проверять работу на разных устройствах.

Надеюсь, вы уже познакомились с базовым примером по созданию собственного браузера. Рассмотрим дополнительные возможности элемента WebView.

Загружаем локальные страницы и картинки

Если вы хотите загружать в WebView страницы не из интернета, а со своего приложения, то разместите нужные файлы в папке assets, например, assets/mypage.html. Доступ к файлу вы можете получить через конструкцию file://android_asset:

Аналогично поступаем с картинками, которые встречаются в html-файле

Также можно загрузить файл из папки res/raw:

Если картинка находится на внешнем накопителе, то попробуйте вариант:

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

Загружаем данные при помощи loadData() и loadDataWithBaseURL()

Данные можно загрузить с помощью метода loadData():

Если текст простой, то этот способ подойдёт. Но в данном примере встречается символ процента, который относится к спецсимволам и часть текста может оказаться недоступной. Если в тексте встречаются подобные символы, то лучше использовать метод loadDataWithBaseURL():

Если вам приходится использовать loadData(), то спецсимволы можно заменить при помощи метода replace():

Проблемы с кодировкой

У меня есть программа в Google Play, использующая WebView. К моему удивлению, некоторые пользователи жаловались, что текст нечитаем, так как они видят только кракозябры. Особенно много жалоб было от пользователей с планшетами. Оказалось, что проблема довольна распространённая и обсуждается на форумах. Танцы с бубнами (установка явной кодировки UTF-8) не помогают. Нашёл один ответ, который у некоторых заработал, на всякий случай я его здесь оставлю.

Но я рекомендую просто использовать метод loadDataWithBaseURL(). Работает стабильно.

Методы

У WebView есть множество методов, которые позволяют добиваться полной функциональности как у обычного браузера — обновить страницу, перейти на предыдущую страницу и т.д. Часть методов представлена ниже:

Используем зум для просмотра

Не забывайте, что WebView можно использовать не только для просмотра html-страниц, но и для просмотра изображений. Поэтому данный компонент вполне можно использовать просмотра картинок с котиками, к тому же вы можете включить встроенный механизм масштабирования:

Прозрачность

Устанавливать прозрачность лучше программно. Встречал жалобы, что через XML это свойство не работает.

WebView в Lollipop

В Android 5.0 компонент доступен в Google Play (Android System WebView) и его можно обновлять на устройстве.

Компонент теперь основывается на движке Chromium и поддерживает следующие новинки.

Можно ознакомиться с некоторыми примерами — GoogleChrome/chromium-webview-samples. Там есть примеры с WebRTC, полноэкранным режимом, касаниями экрана, выбора файла, работой с JavaScript-сценариями.

Кроме того, стал доступен Safe Browsing — механизм, предупреждающий об опасных ссылках. Включается через манифест.

Советы

Если вы заметили, что экран мерцает во время загрузки WebView, то поменяйте фон. Мерцание происходит из-за смены фона приложения (темы), на белый фон по умолчанию для WebView, а потом на фон, который прописан на странице.

Касания экрана

Так как поддерживаются касания экрана, то старайтесь использовать на веб-странице визуальные эффекты нажатия кнопок и других элементов при помощи псевдокласса :active, например, так:

Настройки

В API 24 появилась возможность открыть окно настроек и выбрать движок для WebView:

Ночной режим

Появилась поддержка тёмной темы в последних версиях WebView.

За ночной режим отвечает класс WebViewFeature, который имеет в своём составе коллекцию различных возможностей. Проверить поддержку той или иной возможности можно через isFeatureSupported().

Всего три варианта для тёмной темы.

  • FORCE_DARK_OFF
  • FORCE_DARK_AUTO
  • FORCE_DARK_ON

Источник

Текст с разметкой в android.widget.TextView

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

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

К счастью, самый обычный TextView обладает неожиданно потрясающей функциональностью по разметке текста и может использоваться как в качестве отдельного элемента, так и служить целой страницей, будучи несравненно легковеснее, чем WebView.

Я реализовал весь, необходимый мне функционал и выяснил ещё несколько довольно интересных вещей, столкнувшись с некоторым количеством подводных камней (впрочем, не очень острых). Можно сказать, всё нижеописанное — руководство по созданию достаточно мощной справочной системы в своём приложении практически даром.

Читайте также:  Стандартная клавиатура для андроида

Задачи

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

Содержимое страниц берётся из строк в ресурсах приложения, а изображения являются drawable-ресурсами. Небольшие изменения в коде позволят использовать другие расположения.

Создание приложения

Любым удобным нам способом создаём обычное приложение:

Немного пояснений к манифесту. Если с первой Activity всё понятно, вторая (AnotherActivity) содержит некие дополнительные описатели.

android:exported=«false» необходимо для того, чтобы компилятор не выдавал предупреждения о том, что мы забыли что-то прописать в экспортируемом компоненте. На мой взгляд, чисто декоративный момент, но чем меньше жёлтых треугольничков — тем спокойнее.

Раздел intent-filter содержит описатели того, каким образом и при каких обстоятельствах будет происходить запуск Activity.

означает, что можно запустить Activity ссылкой вида activity-run://AnotherActivityHost?params.

Значения action и category необходимы системе для того чтобы обнаружить и запустить Activity.

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

Строки, содержащие разметку, должны иметь аттрибут formatted со значением false, а содержимое должно передаваться в блоке CDATA, чтобы у компилятора не было претензий к разметке и специальным символам. В данном примере признаком статьи будет префикс article_ в названии строки.

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

Изображения могут быть формата jpg, png или gif без анимации. Анимированный gif отображается статичной картинкой. Расположение стандартное для ресурсов, для дисплеев разной плотности можно подготовить свой вариант картинки. В данном примере все изображения находятся в drawable-nodpi

Как всё работает

Рассмотрим некоторые части кода подробно.

TextView используемый нами в качестве браузера, требует особой инициализации:

tvContent.setLinksClickable(true); указывает на то, что ссылки в данном элементе реагируют на нажатие.

tvContent.setMovementMethod(new LinkMovementMethod()); назначает способ навигации по элементу. Использованный нами LinkMovementMethod интересен сам по себе и, возможно, заслуживает отдельной статьи. Я лишь скажу, что при необходимости более полного контроля можно создать его наследника, переопределенные методы которого позволят отслеживать все действия со ссылками в элементе.

В данном методе происходит получение строки по идентификатору из строковых ресурсов, её преобразование из HTML в специальный объект Spanned, затем ещё одно преобразование в Spannable и установка в TextView в качестве содержимого. Всё это кажется довольно громоздким, но тому есть причины.

В TextView, на мой взгляд, странный порядок обработки спанов — с конца списка. При естественном расположении спанов после преобразования строки из HTML, изменения внешнего вида вложенных спанов перекрываются свойствами спанов, их содержащих. Для нормального отображения приходится буквально выворачивать маркировку наизнанку с помощью метода revertSpanned:

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

Более интересен нам будет Html.TagHadler:

Здесь у нас происходит несколько интересных вещей.

При преобразовании из HTML в Spanned методом Html.fromHtml, обрабатываются тэги br , p , div , em , b , strong , cite , dfn , i , big , small , font , blockquote , tt , a , u , sup , sub , h1. h6 и img . В случае, если тэг не опознан, вызывается Html.TagHandler (если, конечно, он передан в вызов).

Мы проверяем, не является ли переданный тэг «нашим» и если это так, создаём соответствующий Span — элемент разметки, а затем накладываем его на текст. Я создал несколько собственных Span-ов, они будут рассмотрены далее. Как правило, Span-ы наследуются от android.text.style.CharacterStyle.

К сожалению, у меня не получилось малой кровью добиться центрования отдельных строк или абзацев, а встроенной возможности для этого не существует. Также, нельзя прочесть атрибуты тэга из xmlReader, поскольку он реализован не полностью. По этой причине пришлось изобретать свой способ передачи параметров: значение является частью тега. В нашем примере таким образом передаётся значение цвета в тэге color, преобразовываемом в ParameterizedSpan. Получается что-то вроде красный . Это достаточно ограниченный и не очень удобный способ, но иногда лучше такой, чем никакого.

Этот код делает следующее: В случае, если передан открывающий Span, он добавляется к концу строки в текущем её виде. В случае, если Span закрывающий, мы находим в строке его открывающий аналог, запоминаем его положение, затем удаляем и добавляем новый, но уже с информацией о начальном положении и длине.

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

Это Span общего назначения и с его помощью можно задать большинство параметров стиля текста. Его можно использовать как базу для создания стилей текста из собственных тэгов.

Этот класс описывает элемент, который по нажатию на него обеспечивает переход к статье, чей идентификатор является его параметром. Здесь я применил производное от способа, описанного мной ранее: сам тэг является собственным параметром, а его класс определяется префиксом article_. Поднимемся выше, к описанию Html.TagHandler:

Обработчик тэгов, увидев тэг, начинающийся на article_, создаёт ArticleSpan, задавая ему в качестве параметра название тэга. Элемент, при нажатии на него, вызывает метод MainActivity.setArticle, после чего в TextView устанавливается новый текст.

Читайте также:  Изменение разрешения экрана android режим разработчика

Здесь реализован элемент, получающий параметр явно и отдельно от своего имени. Претензия на своего рода стандарт именования тэгов, раз уж нельзя передавать атрибуты.

Конечно, всё описанное является вариациями одного принципа, каждый выберёт то, что ему удобнее.

Вызов Activity

В HTML мы видим следующее:

При нажатии на ссылку, происходит вызов AnotherActivity с передачей параметров в Intent. Эти параметры можно получить и использовать:

Использованные материалы

Следующие материалы очень ускорили создание данной статьи, да и, чего уж там, сделали его вообще возможным:

Я очень рад, что существует на свете StackOverflow.com.

Архив с исходниками проекта

Архив с исходными текстами и ресурсами проекта можно взять здесь.

Источник

Пользовательский интерфейс. View, основные атрибуты

Пользовательский интерфейс

Любое приложение отображает пользователю графический интерфейс. На картинке ниже вы можете увидеть примеры текстовых элементов ( TextView ), кнопок ( Button ), картинок ( ImageView ).

Пользовательский интерфейс представлен layout файлом (рус. Макетом), который создаётся, используя язык разметки XML. Макет определяет структуру пользовательского интерфейса экрана. Все элементы макета построены с использованием иерархии объектов View и ViewGroup . View – компонент, который пользователь может видеть и взаимодействовать с ним. В то время как ViewGroup является невидимым контейнером, который определяет структуру макета, как показано на рисунке.

Объекты View обычно называют «виджетами». Они могут быть представлены одним из классов-наследников, таких как Button , TextView , ImageView . Объекты ViewGroup обычно называют «контейнерами». Они определяют, как именно будут располагаться элементы внутри экрана. Подробнее с ViewGroup мы познакомимся в следующих уроках.

Вы можете работать с макетами двумя способами:

  • Объявлять элементы пользовательского интерфейса в XML коде. Android предоставляет простой XML файл, в котором можно добавлять разные View и ViewGroup вручную. Вы также можете использовать редактор макетов Android Studio, чтобы создать свой XML-макет, не заглядывая в XML код.
  • Создавать элементы макета во время выполнения программы из Java кода. Приложение может создавать объекты View и ViewGroup (и управлять их свойствами) программно.

В этом уроке мы подробнее будем рассматривать именно первый вариант. Откройте файл activity_main.xml . Для ознакомления с синтаксисом языка XML мы будем вносить изменения в этот файл.

XML синтаксис

XML – язык разметки, определяющий теги (элементы) и их атрибуты. Язык очень похож на HTML. Давайте разберём на примере.

Тег ограничивается скобками . Название тега в данном случае – LinearLayout . Всё, что находится между скобками – называется атрибутами. В примере два атрибута:

Атрибуты состоят из названия и значения, которые разделены символом = , причём значение атрибута всегда пишется в кавычках. У атрибута android:layout_width=»match_parent» название – android:layout_width , а значение – match_parent .

После открытия тега, его обязательно надо закрывать. Это можно сделать используя конструкцию (в примере – ).

У элемента могут быть вложенные элементы:

Если у какого-то тега нет вложенных элементов, то лучше сократить закрывающийся тег, используя конструкцию . Обратите внимание на тег TextView :

Пример макета

Layout должен содержать только один корневой элемент, который должен быть объектом View или ViewGroup (обычно используют ViewGroup ). После того, как вы определили корневой элемент, вы можете добавить дополнительные объекты в качестве дочерних элементов, чтобы постепенно создавать пользовательский интерфейс. Давайте изменим файл activity_main.xml . Например, вот код XML-макета, который использует контейнер LinearLayout в качестве корневого элемента и два виджета внутри него: TextView и Button .

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

Связь XML и Java кода

Когда мы запускаем приложение, каждый файл макета XML компилируется в ресурс View . Связь XML файла и Activity происходит в методе onCreate класса MainActivity . Этот код также сгенерировала Android Studio при создании Activity .

Связь происходит при вызове метода setContentView(R.layout.activity_main) . Обращаться к layout файлу нужно в виде R.layout.имя_файла . Это связано с внутренним хранением ресурс файлов в Android системе. В нашем случае файл по умолчанию называется activity_main.xml , поэтому указываем R.layout.activity_main (постфикс xml опускается).

Метод onCreate() вызывается Android системой во время загрузки приложения (эту тему рассмотрим подробнее в следующих уроках).

XML Атрибуты

Каждый объект View и ViewGroup поддерживает множество атрибутов XML.

Вы можете заметить, что в названии атрибутов есть префикс android . Этот префикс называют пространством имён (англ. namespace). В данном случае он означает, что атрибуты объявлены в библиотеке android . Также вы могли заметить, что у корневого элемента в макете обязательно указывается атрибут xmlns:android=»http://schemas.android.com/apk/res/android» . Это сделано для объявления пространства имён.

Некоторые атрибуты специфичны для конкретного элемента. Например, TextView поддерживает атрибут android:textSize (русс. размер текста). Атрибуты наследуются View объектами при расширении класса другого виджета. Некоторые из атрибутов являются общими для всех виджетов, поскольку они наследуются от корневого класса View (например, текст – android:text , ширина – android:layout_width , высота – android:layout_height , идентификатор – android:id ).

Атрибут android:text

Атрибут android:text отвечает за текст, который будет отображаться на экране:

Обязательные атрибуты android:layout_width, android:layout_height

У любого View компонента необходимо объявить атрибуты android:layout_width (русс. ширина макета), android:layout_height (русс. высота макета), иначе приложение не скомпилируется.

Существует три варианта указания ширины и высоты:

  • фиксированный размер в dp . Density-independent Pixel (сокр. dp) – это виртуальный пиксель, основанный на физической плотности экрана устройства. Android переводит это значение в соответствующее количество реальных пикселей для разных экранов.
  • wrap_content означает, что элемент занимает место, необходимое для отрисовки его содержимого.
  • match_parent означает, что элемент занимает столько же места, сколько и родительский элемент. Раньше вместо этого значения использовалось fill_parent . Но это устаревший вариант, поэтому не используйте его.

Создадим три TextView , чтобы показать эти значения:

В данном случае при размере wrap_content TextView занимает столько же места, сколько и текст в нём. Вы можете изменить текст, чтобы убедиться, что размер текста и элемента TextView будут совпадать.

Читайте также:  Ea sports android downloads

Вы могли заметить, что в примере мы использовали атрибуты android:background (русс. цвет фона), android:marginTop (русс. отступ сверху), android:textColor (русс. цвет текста), android:textSize (русс. размер текста) для наглядности. Сейчас мы рассмотрим эти атрибуты детальнее.

Атрибут android:textSize

Атрибут android:textSize отвечает за размер текста, как вы догадались. Разберём на примере:

Размер текста нужно указывать в единицах sp (Scale-independent Pixels). Отличие от dp состоит в том, что этот размер изменяется в зависимости от настроек размера шрифта в телефоне. В Android системе у пользователя есть возможность в настройках изменить шрифт в своём телефоне на крупный, средний или маленький. Чтобы текст в приложении автоматически изменился вместе с этой настройкой рекомендуется использовать единицы sp для текста.

Атрибут android:background

Атрибут android:background определяет фоновый цвет элемента. Когда вы указываете атрибут android:background , то видите точно, сколько места занимает элемент. Разберём на примере:

Давайте разберём запись android:background=»#00FF00″ . #00FF00 – простой способ закодировать любой цвет. Вы можете генерировать нужные цвета онлайн на этом сайте. Для самых любопытных ниже объяснение, как работает задание цветов.

Цвет задаётся в формате ARGB. Это аббревиатура расшифровывается, как Alpha Red Green Blue. Дело в том, что любой цвет можно получить из сочетания в разной степени 3 цветов: красного, зелёного и синего. Также цвета могут быть прозрачными, именно это обозначает слово Alpha.

Чтобы задать цвет мы указываем символ # и 3 байта в шестнадцатеричной системе, которые отвечают за каждый цвет. Первый байт отвечает за красный цвет, второй – за зелёный, третий – за синий.

В данном примере мы указали, что красного цвета будет 00 , зелёного цвета будет FF (максимальное значение), и синего будет 00 . Поэтому фон стал зелёным. Также можно не писать второе число, если оно такое же, как и первое. Т.е. мы можем записать этот же цвет : android:background=»#0F0″ . Если хотите узнать ещё больше о RGB формате, то читайте здесь.

Атрибут android:textColor

Атрибут android:textColor похож на атрибут android:background только он задаёт цвет текста:

Атрибут android:textStyle

Атрибут android:textStyle отвечает за стиль текста. Его возможные значения:

  • normal – обычный текст (применяется по умолчанию, если вы не указали атрибут android:textStyle ).
  • bold – толстый.
  • italic – курсив.

Атрибут android:id

Атрибут android:id у View позволяет работать с ней из Java кода и ссылаться на эту View внутри макета. Покажем на примере работы с View элементом из Java кода:

Символы @+id/ в начале строки указывают, что будет создан новый идентификатор. После этого следует новое имя ресурса, которое должно быть создано и добавлено к нашим ресурсам (в данном случае – text ). Из java кода к этому элементу можно будет обратиться с помощью вызова R.id.text .

С помощью вызова метода findViewById(R.id.text) можно связать View из XML макета с Java объектом TextView . После этого можно вызывать любые методы, которые есть у данного объекта. Для примера мы вызвали метод setText() и указали текст Text from java code .

В результате увидим, что отобразился тот текст, который мы указали из Java кода:

Атрибуты android:padding, android:layout_margin

Рассмотрим атрибуты, которые задают отступы элементов:

  • android:padding (top, bottom, right | end, start | left)
  • android:layout_margin (top, bottom, right | end, start | left)

В xml коде они указываются так:

Параметры (top, bottom, right | end, start | left) означают, с какой стороны вы хотите сделать отступ. Параметры right | end , start | left означают практически одно и тоже. Только start, end добавляют поддержку для стран, в которых тексты читаются справа налево. Поэтому рекомендуется использовать их вместо значений left , right . Эти атрибуты поддерживаются с 17 версии устройств, значит мы можем их использовать (помните, что при создании проекта мы указали, что поддерживаем устройства 21 версии и выше).

Если указать padding , layout_margin без всякого параметра, то отступ будет сделан со всех сторон. Основное различие двух атрибутов состоит в том, что padding делает отступ внутри элемента, а layout_margin делает отступ снаружи. Пример:

Можно сделать тоже самое, указывая отступы со всех сторон явно:

Атрибуты android:gravity, android:layout_gravity

Атрибуты android:gravity и android:layout_gravity отвечают за выравнивание. Ключевое отличие состоит в том, что android:gravity отвечает за выравнивание содержимого внутри элемента, а layout_gravity отвечает за выравнивание элемента относительно родительского контейнера. Разберём на примере:

В данном примере текст в первом TextView выровнен по правому краю, т.к. мы указали атрибут android:gravity=»end» . Второй элемент прижался к правой стороне родительского контейнера, потому что указан атрибут android:layout_gravity=»end» .

Также у этого атрибута могут быть другие значения, которые указывают, как именно выровнять элемент. Перечислим основные из них: top, bottom, start, end, center, center_horizontal, center_vertical

Различные значения можно комбинировать, используя символ | . Если хотим выровнять содержимое по правому нижнему углу, то можем использовать значение end|bottom .

Верите или нет, профессиональные разработчики не запоминают всё – поиск информации является ключевой частью работы. Поэтому не пытайтесь запомнить все View объекты и атрибуты сразу. Google сделал специальный словарь, в котором вы можете найти тот компонент, атрибут или класс, который вам необходим.

Заключение

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

Источник

Оцените статью