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