В моей разработке встала задача – динамически (программно) создать объект типа View и установить его размеры. Как известно, размеры можно задать как в физических пикселях, так и платформо-независимых пикселях (
dip).
Кратко говоря – все расширение экрана мобильного телефона принимается в 320dp. Оно одинаково как для телефона с расширением в 800×480 физических пикселей, так и для телефона с размерами 400×240 физических пикселей (как в моём Samsung Galaxy3 или GT-I5800 ). Т.е. телефон сам автоматически преобразовывает dip-пиксели в физические пиксели экрана.
При проектировании дизайна с помощью xml-файлов возможно задать как dip, так и пиксели. Но при разработке приложения иногда необходимо визуальные элементы создавать программно. В данном случае у объектов View не предусмотрена возможность установки размеров в dip: методы setHeight, setWidth, setMax/MinHeight, setMaxMinWidth принимают только физические пиксели. Собственно, динамически (программно) невозможно также задать и стиль (style) для View. Почему разработчики Android не реализовали очевидно необходимые методы – мне до сих пор не понятно.
Выход, собственно есть, пусть и не очень удобный. Необходимо размеры указывать в ресурсах, извлекать их в программе и подставлять в метод getDimension или getDimensionPixelOffset. Первый метод возвращает тип float (т.е. точное значение преобразования dip в pixels). Второй метод возвращает int, который можно использовать для подстановки в методы установки размеров View.
Поясню на примере: программно создать объекта типа ImageView и задать ему размер 40dip.
1) Создайте в папке ресурсов какой-либо *.xml файл, который будет хранить данные о размерах устанавливаемых объектов. Я назвал файл attr.xml, но вы можете назвать его как угодно.
2) В XML-файле должно содержаться:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Требуемый размер в dip -->
<dimen name="app_list_row_size">40dip</dimen>
</resources>
3) Участок Java-кода, который создаёт изображение ImageView и назначает ему dip-размеры:
// преобразуем dip-пиксели в физические пиксели
int row_height = getResources().getDimensionPixelOffset(R.dimen.app_list_row_size);
// создание объекта ImageView
ImageView iv = new ImageView(this);
// устанавливаем максимальные размеры для ImageView в 40dip
iv.setMaxHeight(row_height);
iv.setMaxWidth(row_height);
Как видите – ничего сложного, но геморройно. Использование метода getDimensionPixelOffset позволяет нам преобразовать «виртуальные» пиксели (dip) в физические, тем самым обеспечив одинаковое отображение ImageView на различных телефонах.