Вывод картинок для android

ImageView

Общая информация

Компонент ImageView предназначен для отображения изображений. Находится в разделе Widgets.

Для загрузки изображения в XML-файле используется атрибут android:src, в последнее время чаще используется атрибут app:srcCompat.

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

  • setImageResource(int resId) — загружает изображение по идентификатору ресурса
  • setImageBitmap(Bitmap bitmap) — загружает растровое изображение
  • setImageDrawable(Drawable drawable) — загружает готовое изображение
  • setImageURI(Uri uri) — загружает изображение по его URI

Метод setImageResource()

Сначала нужно получить ссылку на ImageView, а затем используется идентификатор изображения из ресурсов:

Метод setImageBitmap()

Используется класс BitmapFactory для чтения ресурса изображения в объект Bitmap, а затем в ImageView указывается полученный Bitmap. Могут быть и другие варианты.

Метод setImageDrawable()

Если у вас есть готовое изображение, например, на SD-карте, то его можно использовать в качестве объекта Drawable.

Drawable можно получить и из ресурсов, хотя такой код выглядит избыточным, если можно сразу вызвать setImageResource().

Метод setImageURI()

Берётся URI файла изображения и используется в качестве источника изображения. Этот способ годится для работы с локальными изображениями.

Загружаем Drawable через URI.

Другие методы

Также вам часто придется использовать методы, связанные с размерами и масштабированием: setMaxHeight(), setMaxWidth(), getMinimunHeight(), getMinimunWidth(), getScaleType(), setScaleType().

Масштабирование через свойство Scale Type

Для масштабирования картинки в ImageView есть свойство Scale Type и соответствующий ему атрибут android:scaleType и перечисление ImageView.ScaleType.

  • CENTER
  • CENTER_CROP
  • CENTER_INSIDE
  • FIT_CENTER
  • FIT_START
  • FIT_END
  • FIT_XY
  • MATRIX

Чтобы увидеть разницу между разными режимами, желательно использовать большую картинку, превосходящую по ширине экрана устройства. Допустим, у нас есть простенькая разметка:

Для наглядности я задал красный цвет для фона ImageView.

Режим android:scaleType=»center» выводит картинку в центре без масштабирования. Если у вас будет картинка большего размера, то края могут быть обрезаны.

Режим android:scaleType=»centerCrop» также размещает картинку в центре, но учитывает ширину или высоту контейнера. Режим попытается сделать так, чтобы ширина (или высота) картинки совпала с шириной (или высотой) контейнера, а остальное обрезается.

Режим android:scaleType=»centerInside» масштабирует картинку, сохраняя пропорции. Можно увидеть задний фон контейнера, если его размеры отличаются от размера картинки.

Режим android:scaleType=»fitCenter» (по умолчанию) похож на предыдущий, но может не сохранять пропорции.

Если выбрать режим android:scaleType=»fitStart», то картинка прижимается к левому верхнему углу и таким образом заполняет верхнюю половину контейнера.

Значение android:scaleType=»fitEnd» сместит картинку в нижнюю часть контейнера.

Режим android:scaleType=»fitXY» растягивает/сжимает картинку, чтобы подогнать её к контейнеру. Может получиться вытянутая картинка, поэтому будьте осторожны.

Последний атрибут android:scaleType=»matrix» вывел картинку без изменений в левом верхнем углу с обрезанными краями.

Атрибут android:adjustViewBounds=»true»

При использовании атрибута scaleType=»fitCenter» из предыдущего примера Android вычисляет размеры самой картинки, игнорируя размеры ImageView. В этом случае ваша разметка может «поехать». Атрибут adjustViewBounds заставляет картинку подчиниться размеру компонента-контейнера. В некоторых случаях это может не сработать, например, если у ImageView установлен атрибут layout_width=»0dip». В таком случае поместите ImageView в RelativeLayout или FrameLayout и используйте значение 0dip для этих контейнеров.

Читайте также:  Geekbench 5 для андроид

Загрузка изображения из галереи

Предположим, у вас есть на экране компонент ImageView, и вы хотите загрузить в него какое-нибудь изображение из галереи по нажатию кнопки:

Намерение ACTION_PICK вызывает отображение галереи всех изображений, хранящихся на телефоне, позволяя выбрать одно изображение. При этом возвращается адрес URI, определяющий местоположение выбранного изображения. Для его получения используется метод getData(). Далее для преобразования URI-адреса в соответствующий экземпляр класса Bitmap используется специальный метод Media.getBitmap(). И у нас появляется возможность установить изображение в ImageView при помощи setImageBitmap().

На самом деле можно поступить ещё проще и использовать метод setImageURI.

Сравните с предыдущим примером — чувствуете разницу? Тем не менее, приходится часто наблюдать подобный избыточный код во многих проектах. Это связано с тем, что метод порой кэширует адрес и не происходит изменений. Рекомендуется использовать инструкцию setImageURI(null) для сброса кэша и повторный вызов метода с нужным Uri.

В последних версиях системных эмуляторов два примера не работают. Проверяйте на реальных устройствах.

Получить размеры ImageView — будьте осторожны

У элемента ImageView есть два метода getWidth() и getHeight(), позволяющие получить его ширину и высоту. Но если вы попробуете вызвать указанные методы сразу в методе onCreate(), то они возвратят нулевые значения. Можно добавить кнопку и вызвать данные методы через нажатие, тогда будут получены правильные результаты. Либо использовать другой метод активности, который наступает позже.

Копирование изображений между ImageView

Если вам надо скопировать изображение из одного ImageView в другой, то можно получить объект Drawable через метод getDrawable() и присвоить ему второму компоненту.

Примеры

В моих статьях можно найти примеры использования ImageView.

Источник

Пишем игру для Android. Часть 2 — Вывод рисунка на экран и его перемещение

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

Сегодня мы займемся графикой. Вывод изображения на экран телефона в Android задача почти тривиальная. Не будем ходить вокруг да около, а сразу займемся делом. Для начала выведем изображение робота в верхнем левом углу экрана. Для работы с графикой предпочтительно использовать png формат. Наш рисунок будет называтьсяdroid_1.png и иметь размер 20×20 пикселей. Для того, чтобы с рисунком стало можно работать из приложения, просто скопируйте его в папку/res/drawable-mdpi вашего проекта. Проще всего это сделать, перетащив файлик в соответствующую папку в дереве проектов в Eclipse.

Читайте также:  Облако icloud для андроид

Кстати, обратите внимание, в проекте существует несколько папок drawable. Дело в том, что ваша программа может запускаться на устройствах с разными размерами и разрешениями экрана, поэтому имеет смысл подготовить несколько наборов графических файлов, отличающихся размером картинок. В зависимости от того, где будет работать программа, выбирается тот или иной набор. Я выбрал папку drawable-mdpi, которая соответствует устройствам со средней плотностью точек на экране.

Откройте файл MainGamePanel.java и измените метод onDraw(Canvas canvas)

Метод drawBitmap выводит изображение droid_1.png на экран, причем левый верхний угол этого изображения помещается в точку с координатами x=10, y=15 (напоминаю, ось x направлена вправо, y — вниз, начало координат — верхний левый угол экрана). Для вывода изображения мы использовали id нашего ресурса (картинки внутри папки res), то есть droid_1. При копировании картинки в папку /res/drawable-mdpi Eclipse автоматически внес изменение в файл R.java и имя файла стало его идентификатором. В случае, если вы скопировали файл в папку проекта не через Eclipse, а стандартными средствами вашей операционной системы, то файл R.java не изменится. Более того, если Вы раскроете папку res, то не увидите там только что скопированного файла. Чтобы обновить проект щелкните мышкой по папке res в дереве проектов в Eclipse и нажмите кнопку F5, либо выберите Refresh из контекстного меню.

Помимо метода onDraw нам понадобится также внести некоторые изменения в поток MainThread. Откройте файл MainThread.java и измените метод run()

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

Мы пытаемся инициализировать эту переменную с помощью метода surfaceHolder.lockCanvas() — то есть связать переменную с активной поверхностью view. Этот код помещен в операторные скобки try <. >finally < . >. Если внутри блока try произойдет ошибка, ну например по каким-то причинам нам не удастся заблокировать canvas под себя, то программа не завершится, а выполнится код в блоке finally. Если нам удастся получить в свое распоряжение Canvas, мы передаем его в качестве параметра методу gamePanel.onDraw, внутри которого и осуществляется рисование.

Обратите также внимание на блок synchronised. Включив этот блок в наш код, мы указываем, что получаем surfaceHolder в свое полное распоряжение, блокируем его. Это значит, что до тех пор, пока блок synchronised не закончится, никто другой параллельно не сможет работать с этим объектом.

Описанная выше логика построения программы довольно проста, тем не менее, эта заготовка может быть использована для создания подавляющего большинства аркадных игр. Запустите программу, Вы увидите следующую картинку.

Перемещение изображения

Итак, мы научились выводить картинку на экран, давайте заставим ее двигаться. Как? Используем наши пальцы. Напишем простую реализацию drag and drop функции (кстати, более подробно об drag and drop рассказанов этой статье). Чтобы переместить рисунок, мы должны щелкнуть по нему и переместить в точку, соответствующую координатам касания. После того, как пользователь отрывает палец от экрана, координаты этой точки запоминаются и рисунок выводится туда.

Читайте также:  How connect android studio to github

Давайте создадим для нашего робота отдельный класс Droid.java, в котором определим поля для хранения координат и, собственно, рисунка.

Класс очень простой. В нем определены три поля (x,y и bitmap), методы get и set, позволяющие считывать и записывать их значения, а также конструктор, внутри которого происходит начальная инициализация полей класса.

Нам также понадобятся переменные, для хранения состояния робота. В рамках решаемой в данный момент задачи робот может находиться в одном из двух состояний «перетаскивается» или «не перетаскивается». Определить эти состояния можно с помощью логической переменной touched. В момент, когда пользователь коснулся изображения робота, эта переменная должна принимать значение true. False она примет лишь в момент, когда палец будет снят с экрана.

Давайте немного доработаем класс Droid. Добавим в него метод, осуществляющий рисование draw и метод обработки касания handleActionDown.

Методы draw и handleActionDown обсудим чуть позже, а пока давайте немного поправим код в файле MainGamePanel.java.

В конструкторе класса MainGamePanel мы создали объект droid. В методе onTouchEvent обрабатывается событие касание экрана (MotionEvent.ACTION_DOWN). Если касание произошло, мы вызываем метод handleActionDown, куда передаем координаты. Приведем еще раз листинг этого метода.

Мы сравниваем координаты касания с координатами робота, и если касание происходит внутри прямоугольной области, соответствующей картинке робота, мы изменяем его состояние setTouched(true); в противном случае меняем на false.

Вернемся к методу onTouched. Помимо события MotionEvent.ACTION_DOWN, там обрабатывается событие MotionEvent.ACTION_MOVE. Оно возникает при перемещении пальца по экрану. Внутри обработчика этого события, мы проверяем состояние робота (значение поля touched) и если оно равно true — обновляем координаты робота. В обработчике события MotionEvent.ACTION_UP мы переводим состояние робота в false.

Перейдем к методу Draw. Как помните, он вызывается у нас на каждом шаге игрового цикла. Внутри этого метода мы красим экран в черный цвет, а затем вызываем метод draw объекта droid, который выводит робота на экран.

Можете запустить проект и попытаться поперетаскивать робота по экрану.

Самостоятельное перемещение робота

Давайте теперь придадим нашему роботу самостоятельности и заставим его путешествовать по экрану без вмешательства пользователя. Робот не должен выходить за пределы экрана. Если он дошел до края — он должен изменить направление своего движения. Если наш объект движется самостоятельно — у него должна иметься какая-то скорость. Величина этой скорости влияет на изменение координат. Для понятия «скорость» мы реализуем собственный класс Speed.

Создайте класс Speed.java

Робот имеет горизонтальную и вертикальную составляющую скорости. На каждом шаге цикла к текущей координате робота будим прибавлять соответствующую скорость (на самом деле в физическом смысле правильнее было бы прибавлять величину скорости, умноженную на время прошедшее с прошлой операции перемещения объекта, но мы в целях упрощения не будем так сильно заморачиваться). В конструкторе переменным vx и vy мы присвоили значение 1, то есть на каждом шаге игрового цикла робот будет смещаться на 1 пиксел. Если vx > 0 — робот движется вправо, если vx 0-вниз, vy

Источник

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