4. Как отображать
ImageView
Любому View можно назначить фон (android:background).
Можно загрузить во встроенный браузер (WebView).
Можно отрисовывать через OpenGL и SurfaceView.
Всегда можно отрисовывать вручную через Canvas.
4 Работа с графической подсистемой
5. Класс Bitmap
Представление картинки в памяти.
Может быть mutable и immutable.
Создаётся или напрямую статическим методом
createBitmap, или при чтении из источника данных (файл,
поток, ресурс и т. д.) статическими методами класса
BitmapFactory
До Android API 11 (Android 3.0+) нельзя было считать
картинку в mutable bitmap. Печалька
5 Работа с графической подсистемой
6. Класс Bitmap
Можно узнать размеры изображения.
Можно скопировать/отмасштабировать изображение.
Можно закрасить пиксель/всё изображение/часть
изображения.
Можно хапнуть горя с памятью.
6 Работа с графической подсистемой
7. Класс Bitmap
Память под Bitmap выделяется 2 кусками:
До Android 3.0:
Метаданные и прочая Java-обёртка
Собственно данные о пикселях в нативной куче (которой
Dalvik VM не управляет).
С Android 3.0:
Всё лежит в Dalvik heap.
7 Работа с графической подсистемой
8. Класс Bitmap
Занимает в памяти 4 * width * height
Можно использовать RGB-565 и лишиться прозрачности
Можно использовать ARGB-4444, который давно
deprecated, и картинка не будет радовать цветами.
Dalvik VM не дефрагментирует память, поэтому даже если
в куче хватает места, OutOfMemoryError следит за вами.
8 Работа с графической подсистемой
9. Класс Bitmap
Bitmap освобождает память в 2 случаях:
при сборке мусора и вызове finalize()
при явном вызове метода recycle()
После вызова recycle() картинка не может быть
использована — выбрасывается исключение.
В новых версиях не рекомендуется использовать recycle()
9 Работа с графической подсистемой
10. Класс Bitmap
Делаем recycle(), как только картинка становится не нужна.
Если нужно много изображений — выделяем память при
старте приложения, создаём пул картинок.
При создании через BitmapFactory ставим нужные флаги в
BitmapFactory .Options.
Bitmap bitmap = BitmapFactory.decodeFile(new File("sample.png"));
10 Работа с графической подсистемой
11. Класс Bitmap
Делаем recycle(), как только картинка становится не нужна.
Если нужно много изображений — выделяем память при
старте приложения, создаём пул картинок.
При создании через BitmapFactory ставим нужные флаги в
BitmapFactory .Options.
Bitmap bitmap = BitmapFactory.decodeFile(new File("sample.png"));
Проверить размер картинки
(BitmapOptions.inJustDecodeBounds)
Открыть картинку сразу с масштабированием.
Пробовать ловить OutOfMemoryError и в случае нехватки
памяти грузить картинку с другой цветовой палитрой или
ещё уменьшить размер.
11 Работа с графической подсистемой
12. Класс Drawable
Класс-обёртка для различных видов изображений. Может
содержать внутри:
Bitmap
Геометрическую фигуру с закраской
9-patch изображение
Анимацию
Несколько слоёв
Комбинацию разных Drawable
И кучу всего ещё (читайте про android.graphics.drawable)
12 Работа с графической подсистемой
13. Класс Drawable
BitmapDrawable создаётся «вокруг» обычного Bitmap.
Он создаётся неявно, когда мы ставим картинку в
ImageView через задание android:src.
Мы получаем весь тот же набор проблем с памятью.
Можно достать картинку через getBitmap() и удалить как
раньше.
Обязательно не забудьте установить перед удалением
callback для Drawable в null для сборки памяти (по
умолчанию ставится на вьюху-родитель).
13 Работа с графической подсистемой
14. Класс ImageView
Мы можем задать, как масштабировать изображение.
Можем применить матрицу преобразования, обрезать или
сжать/растянуть в зависимости от размеров.
Подробнее о том, как что преобразуется — здесь:
http://etcodehome.blogspot.com/2011/05/
android-imageview-scaletype-samples.html.
14 Работа с графической подсистемой
15. 9-patch
Когда у нас есть кнопка/поле ввода/любой другой элемент, у
которого мы не знаем размер отображаемых данных — как
ставить фон?
Можем растянуть, но тогда будет некрасиво или появятся
артефакты по углам.
Можем замостить узором, но не всегда это приемлемо
15 Работа с графической подсистемой
17. Ресурсы
Папкам для drawable мы можем ставить квалификаторы
по разрешению (-*dpi)
по размеру (-small, -normal, -large, -xlarge)
Комбинируя эти квалификаторы, можно сделать абсолютно
разный набор графики для телефонов и планшетов.
Если одна и та же картинка совпадает для разных размеров
экрана, кладём её в drawable-nodpi, а в соответствующих
папках ставим на неё ссылку через xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android=http://schemas.android.com/apk/res/android
android:src="@drawable/im_bkg_help_control_normal" />
17 Работа с графической подсистемой
18. State drawables
У кнопки есть несколько состояний: обычное, нажатое,
выделенное.
Возможно, понадобится отображать её разным цветом в
зависимости от ситуации.
Придётся вешать обработчики на все события и менять
фон/изображение?
18 Работа с графической подсистемой
19. State drawables
Нас спасёт State Drawable!
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/button_default"/>
</selector>
Такой же трюк можно провернуть с цветами, установив их для
текста.
19 Работа с графической подсистемой
20. Shape drawables
Простые графические примитивы не обязательно рисовать
руками в любимом фотошопе. Можно их задать через Shape
Drawable в xml.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dip" />
<gradient
android:angle="270"
android:type="linear"
android:startColor="#000000"
android:endColor="#ffffff"/>
</shape>
20 Работа с графической подсистемой
21. Canvas
Наследуемся от View, переопределяем onDraw().
Можем рисовать геометрические примитивы напрямую
руками.
Не стоит забывать о буферизации и не делать слишком
часто перерисовку (быстрее 60 кадров в секунду не будет,
а вот батарею скушать можно бодро).
21 Работа с графической подсистемой
22. Canvas
.moveTo(), .lineTo() — и мы рисуем линии.
Используем класс Path, если нам надо нарисовать
сложную ломаную или много примитивов, тогда отрисовка
будет проходить быстрее.
Класс Picture позволяет кэшировать запросы к Canvas
(отрисовали раз, потом из него воспроизводим гораздо
быстрее) — но он не работает при аппаратном ускорении.
Класс Paint — настройки кисти. Не создавайте лишний раз,
иногда лучше создать статический объект или поле
экземпляра.
22 Работа с графической подсистемой
23. Canvas
Можно нарисовать тот же Bitmap.
Можно написать текст.
Можно «изогнуть» текст вдоль кривой или ломаной.
Можно применять матрицы преобразований.
Можно сохранять и восстанавливать матрицу — OpenGL
для бедных.
23 Работа с графической подсистемой