Как закруглить imageview
Перейти к содержимому

Как закруглить imageview

  • автор:

Урок 162. Графика. Drawable. Shape, Gradient.

Подробно ознакомившись с Bitmap, переходим к другому ключевому объекту графики – Drawable.

Drawable – это абстрактный контейнер для графического объекта. Его главное абстрактное умение – он может нарисовать свое содержимое на предоставленной ему канве. А вот что конкретно он нарисует, зависит уже от реализации. Это может быть, например, тот же Bitmap, если мы используем BitmapDrawable объект. Или это может быть простая геометрическая фигура, если мы используем ShapeDrawable.

Drawable-объекты мы можем создавать сами напрямую в коде. Но для некоторых из них мы можем создать описание в xml-файлах, в папке res/drawable. И когда он нам понадобится, мы укажем id файла, система сама распарсит его и создаст нам нужный объект.

Самое распространенное использование Drawable – это свойство background, которое есть у каждого View. В качестве значения вы можете указать там RGB-цвет или id ресурса из папки res/drawable. Далее система сама по этому значению определит тип и далее:

— если это цвет, то создаст ColorDrawable,
— если это id картинки в res/drawable, то создаст BitmapDrawable
— если это id xml-файла в res/drawable, то распарсит его и вернет соответствующего ему наследника Drawable: StateListDrawable, AnimationDrawable или какой-то другой.

В итоге View получит свой Drawable-объект и сможет его нарисовать.

В общем, как вы поняли, у абстрактного Drawable есть несколько наследников-реализаций и в ближайших уроках мы их рассмотрим. Начнем с тех, которые можно описать в xml. По ним есть отдельная статья в хелпе. Там, правда, есть пара ошибок копипаста, но в остальном все верно.

В этом уроке рассмотрим тег shape>

Project name: P1621_DrawableShape
Build Target: Android 4.4
Application name: DrawableShape
Package name: ru.startandroid.develop.p1621drawableshape
Create Activity: MainActivity

res/layout/main.xml:

res/drawable/shape.xml:

Корневой тег shape и у него же есть одноименный атрибут shape, в котором мы указываем тип фигуры. Мы указали rectangle – это прямоугольник.

Далее, внутри тега shape, идет тег stroke, который позволяет задать нам характеристики линии контура (периметра) фигуры. Мы задаем толщину (width) в 1dp и черный цвет (color).

MainActivity.java:

package ru.startandroid.develop.p1621drawableshape; import android.app.Activity; import android.os.Bundle; import android.widget.ImageView; public class MainActivity extends Activity < ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageView); setDrawable(); >private void setDrawable() < >>

В ImageView пока ничего не отображаем.

Видим ImageView с серым фоном

Перепишем метод setDrawable:

private void setDrawable()

В качестве drawable будем передавать наш файл shape

ImageView теперь отображает прямоугольник с черным контуром.

Посмотрим, какие еще фигуры нам доступны.

Значение атрибута shape = oval, это эллипс

В нашем случае получился круг, т.к. ImageView квадратный.

Значение line даст нам горизонтальную линию

Есть еще фигура кольцо (ring), но о нем чуть позже.

Вернемся к тегу stroke. Добавим в него параметров.

Ширина – 4dp, цвет – синий. Параметры dashWidth и dashGap сделают линию контура пунктирной. dashWidth задает длину пунктирной черточки, а dashGap – расстояние между черточками

Добавим заливку, для этого используется тег solid

Тег solid имеет атрибут color, который позволяет указать цвет заливки фигуры. Мы указали в нем зеленый цвет.

По умолчанию фигура занимает все доступное ей пространство, но мы можем явно указать ее размер с помощью тега size.

Используем тег size с атрибутами width и height

Фигура теперь размером 100х100 и уже не занимает всю доступную ей площадь.

Учтите, что режим отображения зависит от scaleType y ImageView.

Тег padding позволяет нам задать величину отступа внутри фигуры. Это актуально, например, для TextView. Отступ будет учтен при размещении текста.

Мы указали различные отступы со всех 4 сторон.

Если мы теперь повесим эту фигуру в качестве background для TextView, результат будет таким

В качестве заливки мы можем использовать не один цвет, а градиент из двух или трех. Для этого используется тег gradient.

В теге gradient указываем два атрибута-цвета: startColor и endColor.

В результате получится градиент, переходящий из первого цвета во второй.

Градиент вовсе необязательно должен идти слева-направо. Мы можем указать угол направления. Для этого у тега gradient есть атрибут angle

В angle указываем угол 225. Угол 0 означает направление слева-направо, 90 – снизу вверх и т.д. Угол должен быть кратным 45.

В результате видим угол справа-сверху налево-вниз.

Тег gradient позволяет указать третий цвет, который вклинится между start- и end- цветами.

В атрибуте centerColor укажем синий цвет, и он в градиенте будет между красным и зеленым.

Градиент может быть разных типов. Мы рассмотрели тип linear, который используется по умолчанию. Есть еще два типа: radial и sweep.

Тип radial даст нам круговой градиент, а в параметре gradientRadius мы должны указать радиус круга.

Мы можем указать точку центра кругового градиента атрибутами centerX и centerY. Значения этих атрибутов должны быть от 0 до 1.

Центра градиента будет в точке (0.2, 0.2), если принять размеры фигуры за единицу.

Теперь посмотрим, как выглядит градиент sweep.

Для этого типа градиента также можно использовать атрибуты centerColor, centerX и centerY.

Для фигуры прямоугольника мы можем сгладить углы. За это отвечает тег corners.

Атрибут radius позволяет задать радиус закругления сразу для всех углов.

Есть возможность задать свой радиус для каждого угла отдельно.

Кольцо

Нам осталось рассмотреть четвертую фигуру — кольцо. Чтобы его получить, надо в атрибуте shape указать значение ring. Для кольца мы можем настроить два параметра: размер внутреннего радиуса и толщина кольца. Причем, эти два параметра мы можем указывать в абсолютном и относительном выражении.

innerRadius – позволяет указать внутренний радиус, а thickness – толщину кольца. Атрибут useLevel, который нам пока неизвестен, должен быть false, иначе эта фигура у меня не отображалась.

Отобразился круг с внутренним радиусом = 50dp и толщиной = 40dp.

Попробуем указать толщину кольца в относительном значении. Для этого вместо thickness используем thicknessRatio. В этом атрибуте мы указываем во сколько раз толщина кольца будет меньше его ширины.

Ширина кольца = 200 dp, это указано в теге size. thicknessRatio =10, значит толщина кольца = 200 dp / 10 = 20dp.

Теперь укажем внутренний радиус в относительном выражении. Для этого вместо innerRadius используем innerRadiusRatio. В атрибуте innerRadiusRatio указываем во сколько раз внутренний радиус меньше ширины кольца.

Ширина кольца = 200 dp. innerRadiusRatio = 3, значит внутренний радиус кольца = 200 dp / 3 = 67dp.

Как видите, кольцо может занимать не весь свой размер. Это зависит от значений, которые мы задаем для внутреннего радиуса и толщины.

У атрибутов относительного размера есть значения по умолчанию. Т.е. если мы явно не укажем значение для innerRadiusRatio, то по умолчанию он будет равен 3, а thicknessRatio по умолчанию равен 9. Посмотрим, как это выглядит

Мы указали только внутренний радиус. А размер толщины будет вычислен исходя из значения thicknessRatio по умолчанию, т.е. 9.

Теперь не будем указывать инфу о внутреннем радиусе.

Мы указали только толщину кольца, а внутренний радиус будет вычислен исходя из значения innerRadiusRatio по умолчанию = 3.

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

Видим, что кольцо заняло не все 200 dp по высоте, которые мы ему задали в теге size. Почему? Давайте считать исходя из значения по умолчанию.

Внутренний радиус = 200 / 3 = 67. Толщина = 200 / 9 = 22. Т.е. диаметр кольца получается = 22 + 67 * 2 + 22 = 178.

Попробуем подогнать размер кольца под все выделенное ему пространство.

Теперь радиус будет равен 200 / 2.5 = 80, а толщина = 200 / 10 = 20. Диаметр кольца = 20 + 80 * 2 + 20 = 200.

Это видно и на скрине. Кольцо теперь по размеру равно ImageView, т.е. = 200.

Атрибуты абсолютных значений (innerRadius и thickness) имеют приоритет перед относительными (innerRadiusRatio и thicknessRatio).

GradientDrawable

Хоть корневой тег и называется shape, но когда система его распарсит, она создает не ShapeDrawable, а GradientDrawable.

Также, этот объект мы можем сами создать программно.

Перепишем метод setDrawable:

private void setDrawable() < GradientDrawable drawable = new GradientDrawable(GradientDrawable.Orientation.BL_TR, new int[] < Color.RED, Color.GREEN, Color.BLUE, Color.CYAN, Color.MAGENTA >); drawable.setShape(GradientDrawable.RECTANGLE); drawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); drawable.setCornerRadius(40); drawable.setStroke(10, Color.BLACK, 20, 5); imageView.setImageDrawable(drawable); >

Методы set* позволяют нам установить почти все те же параметры, что и в xml-файле.

Но есть и отличия. Например, я не нашел как для GradientDrawable установить значения размеров для кольца. С другой стороны, мы в GradientDrawable можем указать больше трех цветов для градиента.

Т.е. в основном — xml- и java-создание равноценны, но есть некоторые нюансы.

На следующем уроке:

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

Как сделать круглое изображение?

Наверное, стоит написать «как сделать его выглядящим круглым». Круглых изображений не бывает в виртуальном мире, только в физическом :o(. А товарищи всё сказали правильно: нужна прозрачная маска в растре, которая сформирует круглый образ из прямоугольного растра. Давно не работал с изображениями, поэтому сказать ничего конкретного не смогу.

dimasik100200 @dimasik100200 Автор вопроса

odissey_nemo, кто сказал, что их там нет? Нашел библиотеку, которая создает эти круглые изображения без всяких рамок.

Odissey Nemo @odissey_nemo

dimasik100200, я имел в виду, что растры хранятся только в виде прямоугольных матриц пикселов. А круглыми при просмотре их делают прозрачные пикселы в углах этих самых матриц)

Решения вопроса 0
Ответы на вопрос 1
Консультация и разработка мобильных приложений

два варианта
1 на image view наложить другой image view, которое содержит квадрат с прозрачным вырезанным кругом по середине
2 в андроиде есть методы которые позволяют вырезать изображение по шаблону,
нагуглил пример
https://medium.com/@Tarek360/crop-a-shape-from-an-.

Ответ написан более трёх лет назад
Нравится 1 2 комментария
LaitVersion @LaitVersion

А не подскажите какой вариант использовать более правильнее? На мой взгляд первый вариант, так как это требует меньше ресурсов или я ошибаюсь?

зависит от проекта
первый быстрый, я бы сказал для прототипа
второй оптимальнее, так как при вырезании также стоит делать уменьшение изображения, а в дальнейшем кешируется только конечное изображение,
таким образом обработка для картинки происходит один раз, кеш занимает меньше места

Закругление трех краев ImageView

введите сюда описание изображения

Нужно закруглить картинку таким образом, чтобы после загрузки картинка имела такую же форму, как и во время загрузки(см. прикрепленную фотографию) Подскажите, пожалуйста, как это сделать грамотно. Заранее благодарю за помощь! XML ImageView:

shape_incoming_image_message:

Отслеживать

задан 24 авг 2017 в 10:22

Влад Сапожников Влад Сапожников

487 3 3 серебряных знака 16 16 бронзовых знаков

Вы изображения через Picasso подгружаете или через другую библиотеку?

24 авг 2017 в 10:57

через другую, через universal image loader

24 авг 2017 в 11:09

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Я бы сделал вот так:

Устанавливаем shape на форграунд:

ImageView imageView = (ImageView) findViewById(R.id.image); imageView.setImageDrawable(yourImage); imageView.setForeground( getResources().getDrawable(R.drawable.frame_incoming_image_message, null); 

Урок 6. Библиотки для ImageView: Picasso, CircleImageView.

При решении некоторых задач, как и при любой другой работе, нет необходимости придумывать их решения самому. Иногда достаточно просто воспользоваться чьим-то готовым решением. Чаще всего функционал, который другие разработчики могут использовать в своих проектах, оформляется в виде библиотек.

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

Структура файла build.gradle

Первым делом найдём нужный нам файл build.gradle . В проекте с одним модулем их обычно два: один на уровне всего проекта ( top-level ), второй внутри директории app (файл для нашего модуля). Сегодня новые библиотеки мы будем добавлять в файл на уровне модуля. Для этого в дереве папок надо найти узел с названием Gradle Scripts и выбрать файл build.gradle(Module:app) .

AppBuildGradle.png

Отлично, давайте посмотрим на структуру этого файла.

apply plugin: 'com.android.application' android < compileSdkVersion 26 defaultConfig < applicationId "colibri.dev.com.colibritweet" minSdkVersion 17 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" > buildTypes < release < minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' > > > dependencies < implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' >

Как видите, это файл-config (настройки), в котором указываются id приложения, минимальная версия SDK и другие параметры, которые нам пока не важны. Давайте обратим внимание на блок dependencies . Именно в этот блок добавляются библиотеки.

Сейчас нам необходимо добавить зависимость на библиотеку, которая сделает нашу фотографию круглой.

Поиск библиотеки

Каким образом обычно находят библиотеки для Android проектов? Просто ищут их в поиске Google, используя нужные ключевые слова. Давайте попробуем:

SearchLibrary.png

Обычно все библиотеки лежат на сайте github. Поэтому видим, что первая ссылка нам вроде бы подходит. Переходим по ней и ищем строку, чтобы подключить библиотеку, используя нашу систему сборки gradle :

CircleImageViewWiki.png

Сразу видим строку для добавления в build.gradle файл и использование в xml файле. Давайте добавим библиотеку в наш проект. Единственное, что стоит отметить: ключевое слово compile является устаревшим в новой версии gradle , поэтому давайте сразу же его заменим на слово implementation . Видимо, создатель библиотеки не успел обновить Readme файл.

Как только мы добавим строку implementation ‘de.hdodenhof:circleimageview:2.1.0’ в наш gradle файл, вверху сразу появится уведомление, которое говорит нам, что мы должны синхронизировать проект, так как файл изменился. Нажимаем кнопку Sync Now. :

CircleImageViewGradle.png

Отлично, мы подключили с вами нужную библиотеку. Давайте сразу же попробуем использовать её. Для этого в нашем файле activity_user_info.xml давайте заменим использование ImageView на de.hdodenhof.circleimageview.CircleImageView , как сказано в документе библиотеки:

RelativeLayout> de.hdodenhof.circleimageview.CircleImageView android:id="@+id/user_image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher"/>  Остальные элементы снизу не изменились --> RelativeLayout>

Посмотрим, как отобразился наш результат в Preview панели.

UserInfoLayoutCircleImage.png

У нас всё получилось, давайте ещё раз повторим, что надо для того, чтобы добавить библиотеку в проект:

  • Найти нужную нам библиотеку на github (или другом сайте).
  • Посмотреть имя библиотеки + версию.
  • Перейти в файл build.gradle(Module:app)
  • Зайти в блок dependencies
  • Добавить строку implementation «libraryName:libraryVersion»

Добавление и использование библиотеки Picasso

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

Мы будем использовать библиотеку picasso.

Давайте добавим эту библиотеку в наш блок dependencies , как мы это уже сегодня делали. Добавим строку implementation ‘com.squareup.picasso:picasso:2.5.2’ в наш build.gradle файл:

Picasso.png

Теперь осталось применить её в нашем проекте. Она применяется в java коде. В первую очередь нам надо объявить наш ImageView в java коде и связать его с элементов в xml . Давайте сделаем это.

public class UserInfoActivity extends AppCompatActivity < private ImageView userImageView; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_info); userImageView = findViewById(R.id.user_image_view); > >

Здесь ничего сложного. Давайте теперь посмотрим, как нам надо использовать библиотеку picasso на официальном сайте. Видим, что нам всего лишь надо добавить одну строку в нашу Activity :

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView)

Разберём код выше чуть подробнее. Библиотека использует статический класс для удобства. Этому классу необходимы следующие параметры:

  • Первый параметр (передаётся в метод with ) – context . Помним, что в Android пакете Activity наследуется от контекста, т.е. является им, поэтому мы можем передавать ссылку на нашу Activity .
  • Второй параметр (передаётся в метод load ) http://i.imgur.com/DvpvklR.png – это адрес фотографии, которую мы хотим загрузить.
  • Третий параметр (передаётся в метод into ) imageView – это и есть наш userImageView , который будет отображать загруженную фотографию.

Вот и всё, давайте добавим эту строку в нашу UserInfoActivity и запустим приложение.

public class UserInfoActivity extends AppCompatActivity < private ImageView userImageView; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_info); userImageView = findViewById(R.id.user_image_view); Picasso.with(this).load("http://i.imgur.com/DvpvklR.png").into(userImageView); > >

Давайте запустим приложение и посмотрим на результат:

PicassoWithoutInternet.png

Что-то пошло не так, фотография не отобразилась.

У вас фотография могла отобразиться. На эмуляторе у меня локально она отображается, а на реальном устройстве – нет. Давайте добавим логику, позволяющую отображать картинку и на реальном устройстве.

Т.к. мы загружаем фотографию с удалённого хранилища, то нам необходимо объявить в файле AndroidManifest строку, которая будет указывать, что наше приложение использует интернет:

uses-permission android:name="android.permission.INTERNET"/>

Вот как должен выглядеть наш файл после этого:

InternetPermission.png

Теперь запустим приложение и посмотрим результат:

PicassoWithInternet.png

Отлично! Наша фотография загрузилась. Только сделаем фотографию немного меньше. Помним, что сейчас у нашего user_image_view стоят размеры wrap_content . Это означает, что размеры будут меняться в зависимости от размеров фотографий. Давайте поставим фотографии размеры 96dp , чтобы она была похожа по размерам на фотографию в официальном Twitter -клиенте. Изменим два атрибута нашего ImageView .

RelativeLayout> de.hdodenhof.circleimageview.CircleImageView android:id="@+id/user_image_view" android:layout_width="96dp" android:layout_height="96dp" android:src="@mipmap/ic_launcher"/>  Остальные элементы снизу не изменились --> RelativeLayout>

В результате получим:

PicassoWithInternetFixed.png

Видим, что фотография стала занимать меньше места. Отлично, давайте подведём итоги нашего урока.

  • Android проекты используют gradle системы для сборки проекта. Для подключения библиотек используется build.gradle(Module:app) файл.
  • Библиотеки очень легко найти, используя нужные ключевые слова. Чаще всего библиотеки с описанием находятся на сайте github.
  • Все библиотеки подключаются шаблонно. Мы увидели это на примере двух библиотек: для отображения круглой фотографии, для загрузки фотографий с удалённого сервера.
  • Ссылка на репозиторий библиотеки CircleImageView
  • Ссылка на репозиторий библиотеки Picasso

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *