27 February 2021
Денис Колисниченко
Прошу извинения за испорченные скриншоты, но другого способа нет. Надоели твари ворующие материалы и зарабатывающие на них деньги, ничего не создав своего!
В этой статье мы поговорим о создании статической графики путем рисования в объекте View из разметки или же рисования непосредственно на канве. Анимация будет рассмотрена в следующих статьях.
Для рисования на формах и изображениях используется графическая библиотека android.graphics.drawable. Класс Drawable определяет различные виды графики, например BitmapDrawable, ShapeDrawable, LayerDrawable и др.
Существуют два способа определения и инициализации объекта Drawable. Первый заключается в использовании объектов из каталога res/drawable, а второй — в использовании XML-файла со свойствами объекта Drawable.
В Android-приложениях вы можете
использовать изображения следующих фор-
матов:
Примечание
Конечно, для каждого формата есть свое
применение. Формат PNG отлично подходит для изображений кнопок и других
элементов графического интерфейса. Формат JPEG вы будете использовать для
работы с фотографиями — от него никуда не денешься. Формат BMP — это
изобретение Microsoft, вот пусть сами его и используют. Только
у Microsoft есть столько дискового пространства, чтобы хранить изображения в формате
BMP. Формат GIF поддерживает анимацию — это единственное его преимущество,
но позже вы узнаете, что анимацию можно создать средствами Android. Поэтому
вообще не вижу необходимости в этом формате.
Ресурсы изображений помещаются в каталог res/drawable. Во время компиляции программы ресурсы из этого каталога оптимизируются программой aapt. Если вам нужно использовать растровые изображения без оптимизации, поместите их в каталог res/raw — при компиляции файлы из этого каталога не будут оптимизированы утилитой aapt.
Рассмотрим подробнее процесс добавления ресурса в проект. Предположим, что нам нужно добавить в проект два файла — p1.jpg и p2.jpg. Подготовьте три варианта каждого файла — с высоким разрешением, со средним разрешением и с низким разрешением. Значение разрешения зависит от выбранной платформы и от самого мобильного устройства
Файлы с высоким разрешением нужно поместить в каталог res/drawable-hdpi, файлы с низким разрешением — в каталог res/drawable-ldpi, со средним — в каталог res/drawable-mdpi. После этого вернитесь в окно Eclipse, нажмите F5 и в области Package Explorer вы увидите добавленные файлы (рис. 1).
Теперь перейдите на вкладку Images & Media палитры компонентов
и добавьте элемент ImageView. При его добавлении с помощью графического
редактора разметки появится окно, в котором нужно выбрать изображение для
Рис. 7.1. Добавленные графические файлы
Рис. 7.2. Выбор ресурса
Рис. 7.3. Выбранное изображение
отображения в ImageView (рис. 2). Выбранное изображение сразу будет отображено в редакторе разметки (рис. 3).
Далее выбранное изображение появится в редакторе разметки (рис. 7.3), а в файл main.xml будет добавлен код, приведенный в листинге 1. Из листинга 1 я удалил код текстовой надписи, которая добавляется в проект по умолчанию.
Листинг 1. Пример описания элемента ImageView
Обратите внимание (© Денис Колисниченко), что в новом ADT-плагине появилось новое
предупреждение. В редакторе кода оно выглядит как желтый треугольник с
восклицательным знаком напротив кода ImageView. Если подвести к нему указатель
мыши, то вы увидите само предупреждение: Missing contentDescription attribute on image Данное предупреждение не приведет к какой-либо ошибке при
сборке проекта и можно проигнорировать. Но если и вам не нравятся какие-либо
предупреждения и недостатки кода, тогда сначала нужно в файл res/values/strings.xml
добавить новую строку desc. То есть в файл strings.xml
нужно добавить строку: <string name="desc">Описание
картинки</string> Это и будет описание картинки, как вы уже догадались. После
этого нужно обязательно сохранить этот файл, нажав Ctrl + S.
Затем в файл разметки необходимо добавить атрибут contentDescription
для ImageView и сохранить файл разметки: android:contentDescription="@string/desc" После этого предупреждение больше не будет появляться.
Полный код ImageView выглядит так: Напрямую значение атрибута contentDescription указывать не
нужно, потому что получите еще одно предупреждение. Подробнее об этом атрибуте
можно прочитать здесь: https://developer.android.com/reference/android/view/View.html#attr_android:contentDescription Теперь продолжим исследовать область ImageView. Имя
ресурса задается параметром android:src. В коде программы объект Drawable инициализируется так: Resources R =
mContext.getResources(); Drawable exitImage =
R.getDrawable(R.drawable.exit_image); Представим, что вы создали два разных объекта Drawable для одного и
того же ресурса. Если вы потом измените свойство для одного из объектов Drawable, это же
свойство будет автоматически изменено и для второго объекта Drawable, поскольку
они используют один и тот же ресурс. Узнать максимальную высоту и ширину ImageView можно
методами: int getMaxHeight() int getMaxWidth() Метод setImageURI() может использоваться для загрузки
изображения с определенного URL, однако это может привести к задержкам,
связанным с передачей данных по сети. Однако использование этого метода
довольно ограничено и URI должен указываться в формате, понятном операционной
системе Android, это не обычный URI, к которым мы привыкли при работе в
Интернете. Другими словами, если вы укажете URL вроде
https://server.ru/image.jpg, у вас ничего не выйдет. Также некорректно работают метод setImageURI(). Вы
думаете, что можно попробовать загрузить картинку так: imageView.setImageURI(Uri.fromFile(file)); но у вас ничего не получается? Вы не один такой. Данная
проблема описана здесь: https://code.google.com/p/android/issues/detail?id=2733 К сожалению, она пока не решена, поэтому приходится
"изощряться". Итак, что нужно сделать, чтобы загрузить изображение с
URI? Нужно сначала получить объект Drawable, а потом передать его методу getDrawable(): Uri
imgUri=Uri.parse("file:///data/data/MYFOLDER/myimage.png"); d = Drawable.createFromPath(imgUri.getPath()); ImgView.getDrawable(d); Вместо локального файла можно указать удаленный URL. Можно также сначала получить Bitmap из изображения, а
потом конвертировать его в Drawable. В группе
разработчиков Google приводится решение для этого в виде следующей удобной
функции, которая возвращает Bitmap изображения, заданного строкой url: После того, как Bitmap получен - половина дела сделана.
Осталось конвертировать его в Drawable. Это можно сделать так: Bitmap b = getImageBitmap("http://server.ru/image.jpg"); Drawable d = new BitmapDrawable(getResources(),b); Теперь у нас есть объект d, который можно передать методу
getDrawable().
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.sample.glava7.MainActivity" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:layout_marginTop="159dp"
android:src="@drawable/p2" />
%lt/RelativeLayout>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:layout_marginTop="159dp"
android:src="@drawable/p2" />
private Bitmap getImageBitmap(String url) {
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "Error getting bitmap", e);
}
return bm;
}