Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

TextView

Общие сведения
Программная установка текста
Программная установка фона
Реагируем на событие onClick
Многострочный текст
Увеличиваем интервалы между строками
Бой с тенью
Создание ссылок автоматом
Совет: Используйте полупрозрачность с умом
Выделить текст для копирования
Стили

Компонент TextView предназначен для отображения текста без возможности редактирования его пользователем, что видно из его названия (Text - текст, view - просмотр).

Находится в разделе Texts.

TextView - один из самых используемых компонентов. С его помощью пользователю удобнее ориентироваться в программе. По сути, это как таблички: Руками не трогать, По газону не ходить, Вход с собаками воспрещен, Часы работы с 9.00 до 18.00 и т.д., и служит для представления пользователю описательного текста.

Для отображения текста в TextView в файле разметки используется атрибут android:text, например:


android:text="Погладь кота, ...!" 

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


android:text="@string/hello"

Программная установка текста

Программно текст можно задать методом setText():

 
// Инициализируем компонент 
TextView textView = findViewById(R.id.textView);
// задаём текст
textView.setText("Hello Kitty!");
// или с использованием текстовых ресурсов
textView.setText(R.string.hello);

Атрибуты

android:textsize
размер текста. При установке размера текста используется несколько единиц измерения: px (пиксели), dp, sp, in (дюймы), pt, mm. Для текстов рекомендуется использовать sp: android:textSize="48sp", аналог - метод setTextSize()
android:textstyle
стиль текста. Используются константы: normal, bold, italic. Например, android:textStyle="bold" выводит текст жирным
android:textcolor
цвет текста. Используются четыре формата в шестнадцатеричной кодировке: #RGB; #ARGB; #RRGGBB; #AARRGGBB, где R, G, B — соответствующий цвет, А — прозрачность (alpha-канал). Значение А, установленное в 0, означает прозрачность 100%.

Для всех вышеперечисленных атрибутов в классе TextView есть соответствующие методы для чтения или задания соответствующих свойств.

Программно установим размеры текста при помощи setTextSize() с различными единицами измерения.


// 20 DIP (Device Independent Pixels)
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);

// 0.5 inch
textView.setTextSize(TypedValue.COMPLEX_UNIT_IN, 0.5f);

// 10 millimeter
textView.setTextSize(TypedValue.COMPLEX_UNIT_MM, 10);

// 30 points
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, 30);

// 30 raw pixels
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 30);

// 30 scaled pixels
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);

TextView

По умолчанию у компонентов TextView отсутствует фоновый цвет. Чтобы задать цвет, укажите значение Drawable для атрибута android:background. В качестве значения Drawable может использоваться изображение или XML-представление фигуры, включающий ресурс Drawable (поместить в папку res/drawable).

Программная установка фона

В некоторых случаях программисты из-за невнимательности неправильно меняют фон элемента программным способом и удивляются, почему ничего не работает.

Предположим, у вас определён в ресурсах зелёный цвет:


<color name="tvBackground">#337700</color>

Следующий код будет ошибочным:


textview.setBackgroundColor(R.color.tvBackground); // не работает

Нужно так (два варианта):


textView.setBackgroundResource(R.color.tvBackground); // первый вариант
textView.setBackgroundColor(getResources().getColor(R.color.tvBackground)); // второй вариант

Реагируем на событие onClick

Если вы хотите, чтобы TextView обрабатывал нажатия (атрибут android:onClick), то не забывайте также использовать в связке атрибут android:clickable="true". Иначе работать не будет!

Многострочный текст

Если вы хотите создать многострочный текст в TextView, то используйте символы \n для переноса строк.

Например, в ресурсах:


<string name="about_text">
    У лукоморья дуб зелёный;\n
    Златая цепь на дубе том:\n
    И днём и ночью <b>кот учёный</b>\n
    Всё ходит по цепи кругом;\n
    Идёт <b>направо</b> - песнь заводит,\n
    <b>Налево</b> - сказку говорит.</string>

Обратите внимание, что в тексте также применяется простое форматирование.

Также перенос на новую строку можно задать в коде:


textView.setText("Первая строка \nВторая строка \nТретья строка");

Увеличиваем интервалы между строками

Вы можете управлять интервалом между соседними строчками текста через атрибут android:lineSpacingMultiplier, который является множителем. Установите дробное значение меньше единицы, чтобы сократить интервал или больше единицы, чтобы увеличить интервал между строками.


android:lineSpacingMultiplier="0.8"

Бой с тенью

Чтобы оживить текст, можно дополнительно задействовать атрибуты для создания эффектов тени: shadowColor, shadowDx, shadowDy и shadowRadius. С их помощью вы можете установить цвет тени и ее смещение. Во время установки значений вы не увидите изменений, необходимо запустить пример в эмуляторе или на устройстве. В следующем примере я создал тень красного цвета со смещением в 2 пикселя по вертикали и горизонтали. Учтите, что для смещения используются единицы px (пиксели), единицы dp не поддерживаются.


<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="12dp"
    android:text="Бой с тенью"
    android:textSize="80sp"
    android:textStyle="bold"
    android:shadowColor="#ff0000"
    android:shadowDx="2"
    android:shadowDy="2"
    android:shadowRadius="5"/>

TextView с тенью

Программный эквивалент - метод public void setShadowLayer (float radius, float dx, float dy, int color):


TextView textShadow = (TextView)findViewById(R.id.hello);
textShadow.setShadowLayer(
    5f,   //float radius
    10f,  //float dx
    10f,  //float dy 
    0xFFFFFFFF //int color
);

У TextView есть ещё два интересных свойства Auto link (атрибут autoLink) и Links clickable (атрибут linksClickable), которые позволяют автоматически создавать ссылки из текста.

Выглядит это следующим образом. Предположим, мы присвоим элементу TextView текст Мой сайт: developer.alexanderklimov.ru и применим к нему указанные свойства.


<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:autoLink="web"
    android:linksClickable="true"
    android:text="Мой адрес: developer.alexanderklimov.ru" />

При этом уже на этапе разработки вы увидите, что строка адреса сайта после слов Мой адрес: стала ссылкой. Если вы запустите приложение и нажмете на ссылку, то откроется браузер с указанным адресом. Вам даже не придется писать дополнительный код. Аналогично, если указать номер телефона (параметр phone), то запустится звонилка.

У ссылки есть интересная особенность - при длительном нажатии на ссылку появляется диалоговое окно, позволяющее скопировать ссылку в буфер обмена.

Атрибут autoLink позволяет комбинировать различные виды ссылок для автоматического распознавания: веб-адрес, email, номер телефона.

Ссылка в TextView

Цвет ссылки можно поменять через свойство Text color link (XML-атрибут textColorLink), а программно через метод setTextLinkColor().

Программно можно установить ссылки на текст через класс Linkify:


TextView tvDisplay = (TextView)findViewById(R.id.tvDisplay);

String data = "" +
        "Пример использования Linkify для создания ссылок в тексте.\n" +
        "\n" +
        "URL: http://developer.alexanderklimov.ru/ \n" +
        "Email: [email protected] \n" +
        "Телефон: (495)-458-58-29 \n" +
        "Адрес: 10110 ул.Котовского, г.Мышкин \n" +
        "\n" +
        "Классно получилось?";
 
        if(tvDisplay != null) {
            tvDisplay.setText(data);
            Linkify.addLinks(tvDisplay, Linkify.ALL);
        }

Ссылка в TextView

Кроме константы ALL, можно также использовать Linkify.EMAIL_ADDRESSES, Linkify.MAP_ADDRESSES, Linkify.PHONE_NUMBERS. К сожалению, русские адреса не распознаются. В моём случае индекс был распознан как телефонный номер, а город и улица не стали ссылкой.

В таких случаях придётся самостоятельно добавить ссылки в текстах. Например, определим ссылку в ресурсе:


<string name="my_site"><a href="http://developer.alexanderklimov.ru/android">Самый лучший сайт про android</a></string>

Присвоим созданный ресурс тексту в TextView и запустим пример. Сам текст будет выглядеть как ссылка, но реагировать не будет. Чтобы исправить данную проблему, добавим код:


TextView textView = (TextView) findViewById(R.id.textView);
textView.setMovementMethod(LinkMovementMethod.getInstance());

Ссылки в тексте выглядят не совсем удобными. Есть отдельная библиотека, которая улучшает функциональность. Описание проблем и ссылка на библиотеку есть в статье A better way to handle links in TextView - Saket Narayan.

Совет: Используйте полупрозрачность с умом

Если вам нужно установить текст полупрозрачным, то не используйте атрибут android:alpha:


<TextView 
    android:textColor="#fff"
    android:alpha="0.5" />

Дело в том, что такой подход затрачивает много ресурсов при перерисовке.

Атрибут textColor позволяет установить полупрозрачность без потери производительности:


<TextView 
    android:textColor="80ffffff" />

Выделить текст для копирования

По умолчанию, текст в TextView нельзя выделить для копирования. Но в API 11 появилась такая возможность, которая может пригодиться. Делается либо при помощи XML-атрибута android:textIsSelectable, либо через метод setTextIsSelectable().

Добавьте в разметку два компонента TextView и одно текстовое поле EditText для вставки скопированного текста. У первой текстовой метки установим возможность выделения текста декларативно.


<TextView
    android:id="@+id/textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Выдели слово Кот для проверки"
    android:textIsSelectable="true"
    android:textSize="26sp"/>

Для второго компонента возможность выделения создадим программно.


TextView secondTextView = (TextView) findViewById(R.id.textView2);
secondTextView.setTextIsSelectable(true);

Сделайте долгий тап на тексте в любом TextView. Увидите стандартные ползунки для выбора длины текста. Скопируйте текст, сделайте длинный тап в EditText и вставьте текст.

Стили

Выводим разделитель под текстом.


<TextView
    style="?android:listSeparatorTextViewStyle"
    ...
    android:text="Заголовок"/>

Дополнительное чтение

Используем собственные шрифты

Spannable

Продвинутые примеры с TextView

Автоподгонка текста по размеру TextView

Библиотеки

armcha/AutoLinkTextView: AutoLinkTextView is TextView that supports Hashtags (#), Mentions (@) , URLs (http://), Phone and Email automatically detecting and ability to handle clicks. - распознаёт ссылки, номера телефонов, хэштеги.

RomainPiel/Shimmer-android - сияющий текст.

Реклама